← Back to all products

FastAPI Starter Template

$39

Production FastAPI project with auth, database, testing, Docker, CI/CD, and OpenAPI documentation.

📁 19 files🏷 v1.0.0
DockerPythonTOMLJSONMarkdownYAMLFastAPIRedisPostgreSQL

📁 File Structure 19 files

fastapi-starter-template/ ├── LICENSE ├── README.md ├── alembic/ │ └── env.py ├── app/ │ ├── api/ │ │ ├── deps.py │ │ └── v1/ │ │ ├── auth.py │ │ └── users.py │ ├── config.py │ ├── core/ │ │ ├── database.py │ │ └── security.py │ ├── main.py │ ├── middleware/ │ │ └── rate_limit.py │ ├── models/ │ │ ├── base.py │ │ └── user.py │ └── schemas/ │ └── user.py ├── docker/ │ ├── Dockerfile │ └── docker-compose.yml ├── pyproject.toml └── tests/ ├── conftest.py └── test_auth.py

📖 Documentation Preview README excerpt

FastAPI Starter Template

Production-ready FastAPI boilerplate with async SQLAlchemy, JWT auth, and Docker — ship your API in hours, not weeks.

[![Python 3.11+](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/downloads/)

[![FastAPI](https://img.shields.io/badge/FastAPI-0.110+-green.svg)](https://fastapi.tiangolo.com)

[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)

---

What You Get

  • Async-first architecture — SQLAlchemy 2.0 async engine, async session management
  • JWT authentication — Register, login, refresh tokens, role-based access control
  • User management — Full CRUD with pagination, soft-delete, and admin routes
  • Rate limiting — In-memory sliding window middleware (swap for Redis in production)
  • Database migrations — Alembic with async support, auto-generate from models
  • Docker ready — Multi-stage Dockerfile, docker-compose with PostgreSQL & Redis
  • Test suite — AsyncClient fixtures, auth helpers, database isolation
  • Clean project structure — Separation of concerns with dependency injection

File Tree


fastapi-starter-template/
├── app/
│   ├── main.py                  # FastAPI app entry point
│   ├── config.py                # Pydantic settings from env vars
│   ├── models/
│   │   ├── base.py              # SQLAlchemy Base + mixins
│   │   └── user.py              # User model
│   ├── schemas/
│   │   └── user.py              # Pydantic request/response schemas
│   ├── api/
│   │   ├── deps.py              # Shared dependencies
│   │   └── v1/
│   │       ├── auth.py          # Auth routes (register/login/refresh)
│   │       └── users.py         # User CRUD routes
│   ├── core/
│   │   ├── security.py          # JWT + password hashing
│   │   └── database.py          # Async engine + session
│   └── middleware/
│       └── rate_limit.py        # Rate limiting middleware
├── tests/
│   ├── conftest.py              # Test fixtures
│   └── test_auth.py             # Auth endpoint tests
├── docker/
│   ├── Dockerfile               # Multi-stage build
│   └── docker-compose.yml       # Full stack
├── alembic/
│   └── env.py                   # Async migration env
└── pyproject.toml               # Project configuration

Getting Started

1. Clone and configure


cp .env.example .env

*... continues with setup instructions, usage examples, and more.*

📄 Code Sample .py preview

alembic/env.py """ Alembic migration environment with async SQLAlchemy support. Configures Alembic to use the application's async database engine and auto-detect model changes for migration generation. """ from __future__ import annotations import asyncio from logging.config import fileConfig from alembic import context from sqlalchemy import pool from sqlalchemy.ext.asyncio import async_engine_from_config from app.config import settings from app.models.base import Base # Import all models so Alembic can detect them from app.models import user # noqa: F401 config = context.config if config.config_file_name is not None: fileConfig(config.config_file_name) target_metadata = Base.metadata # Override sqlalchemy.url with the application's database URL config.set_main_option("sqlalchemy.url", settings.async_database_url) def run_migrations_offline() -> None: """Run migrations in 'offline' mode — generates SQL without a live connection.""" url = config.get_main_option("sqlalchemy.url") context.configure( url=url, target_metadata=target_metadata, literal_binds=True, dialect_opts={"paramstyle": "named"}, ) with context.begin_transaction(): context.run_migrations() def do_run_migrations(connection) -> None: """Execute migrations against the provided connection.""" context.configure(connection=connection, target_metadata=target_metadata) # ... 28 more lines ...