A comprehensive, production-ready FastAPI backend template with all batteries included for scalable web applications.
- 🔐 Authentication & Security - JWT-based auth with access/refresh tokens, bcrypt password hashing
- 🗄️ Database - Async SQLAlchemy 2.0 with PostgreSQL, connection pooling, and Alembic migrations
- 📦 Repository Pattern - Clean data access layer with generic CRUD operations
- 🔄 Background Tasks - Celery with Redis for async task processing
- 💾 Caching - Redis integration with cache decorators
- 📧 Email - Abstracted email providers (SMTP, console for dev)
- 📁 File Storage - S3 and local file storage abstraction
- 🛡️ Middleware - Correlation ID, request logging, rate limiting, response timing
- 📝 API Versioning - Structured API routes with versioning (
/api/v1/) - 🎯 Type Safety - Full type hints with Pydantic v2 schemas
- 🧪 Testing - Pytest setup with factories and fixtures
- 🐳 Docker - Docker Compose for local development
- Python 3.11+
- PostgreSQL 15+
- Redis 7+
- Docker & Docker Compose (optional, for containerized development)
# Clone and navigate to the project
cd fastapi-template
# Create virtual environment
python -m venv .venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
# Install dependencies
pip install -e ".[dev]"
# Copy environment file and configure
cp .env.example .env
# Run database migrations
alembic upgrade head
# Seed the database (optional)
python -m app.db.seeds.run
# Start the development server
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000# Start all services
docker-compose up -d
# View logs
docker-compose logs -f app
# Stop services
docker-compose down- API: http://localhost:8000
- Swagger Docs: http://localhost:8000/docs
- ReDoc: http://localhost:8000/redoc
fastapi-template/
├── app/
│ ├── main.py # Application entry point
│ ├── core/ # Core modules
│ │ ├── config.py # Pydantic Settings configuration
│ │ ├── security.py # JWT & password utilities
│ │ ├── exceptions.py # Custom exception classes
│ │ ├── dependencies.py # Shared FastAPI dependencies
│ │ └── events.py # Startup/shutdown handlers
│ │
│ ├── api/v1/ # API version 1
│ │ ├── router.py # Route aggregation
│ │ └── endpoints/ # Route handlers
│ │ ├── auth.py # Authentication endpoints
│ │ ├── users.py # User management
│ │ └── health.py # Health checks
│ │
│ ├── models/ # SQLAlchemy models
│ │ ├── base.py # Base model with mixins
│ │ └── user.py # User model
│ │
│ ├── schemas/ # Pydantic schemas
│ │ ├── base.py # Base schemas, response envelope
│ │ ├── user.py # User DTOs
│ │ └── auth.py # Auth DTOs
│ │
│ ├── services/ # Business logic layer
│ │ ├── base.py # Generic service class
│ │ ├── user_service.py # User operations
│ │ └── auth_service.py # Authentication logic
│ │
│ ├── repositories/ # Data access layer
│ │ ├── base.py # Generic repository pattern
│ │ └── user_repository.py # User data access
│ │
│ ├── db/ # Database configuration
│ │ ├── session.py # Session management
│ │ ├── migrations/ # Alembic migrations
│ │ └── seeds/ # Data seeding
│ │
│ ├── middleware/ # Custom middleware
│ │ ├── correlation_id.py # Request tracing
│ │ ├── logging.py # Structured logging
│ │ ├── timing.py # Response timing
│ │ └── rate_limit.py # Rate limiting
│ │
│ ├── workers/ # Background tasks
│ │ ├── celery_app.py # Celery configuration
│ │ └── tasks/ # Task definitions
│ │
│ ├── integrations/ # External service integrations
│ │ ├── cache/ # Redis caching
│ │ ├── email/ # Email providers
│ │ └── storage/ # File storage (S3, local)
│ │
│ └── utils/ # Utilities
│ ├── pagination.py # Pagination helpers
│ ├── filtering.py # Query filtering
│ ├── validators.py # Reusable validators
│ └── helpers.py # Misc helpers
│
├── tests/ # Test suite
│ ├── conftest.py # Pytest fixtures
│ ├── factories/ # Model factories
│ └── integration/ # API tests
│
├── docker-compose.yml # Docker services
├── Dockerfile # Production container
├── Makefile # Development commands
├── pyproject.toml # Project configuration
├── alembic.ini # Migration config
└── .pre-commit-config.yaml # Code quality hooks
Configuration is managed through environment variables using Pydantic Settings.
Create a .env file from the example:
cp .env.example .envKey variables:
| Variable | Description | Default |
|---|---|---|
APP_ENV |
Environment (development, staging, production) | development |
DEBUG |
Enable debug mode | false |
DATABASE_URL |
PostgreSQL connection string | Required |
REDIS_URL |
Redis connection string | Required |
JWT_SECRET_KEY |
Secret for JWT signing | Required in production |
JWT_ACCESS_TOKEN_EXPIRE_MINUTES |
Access token lifetime | 30 |
JWT_REFRESH_TOKEN_EXPIRE_DAYS |
Refresh token lifetime | 7 |
CORS_ORIGINS |
Allowed CORS origins | ["http://localhost:3000"] |
See app/core/config.py for all available settings.
| Method | Endpoint | Description |
|---|---|---|
POST |
/api/v1/auth/login |
OAuth2 password login |
POST |
/api/v1/auth/login/json |
JSON-based login |
POST |
/api/v1/auth/refresh |
Refresh access token |
POST |
/api/v1/auth/password/change |
Change password |
POST |
/api/v1/auth/password-reset/request |
Request password reset |
POST |
/api/v1/auth/password-reset/confirm |
Confirm password reset |
| Method | Endpoint | Description |
|---|---|---|
POST |
/api/v1/users/register |
Register new user |
GET |
/api/v1/users/me |
Get current user profile |
PUT |
/api/v1/users/me |
Update current user |
GET |
/api/v1/users |
List users (admin only) |
GET |
/api/v1/users/{id} |
Get user by ID (admin only) |
DELETE |
/api/v1/users/{id} |
Delete user (admin only) |
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/v1/health/ |
Basic health check |
GET |
/api/v1/health/live |
Kubernetes liveness probe |
GET |
/api/v1/health/ready |
Kubernetes readiness probe |
┌─────────────────────────────────────────────────────┐
│ API Layer │
│ (endpoints, router) │
├─────────────────────────────────────────────────────┤
│ Service Layer │
│ (business logic, validation) │
├─────────────────────────────────────────────────────┤
│ Repository Layer │
│ (data access, queries) │
├─────────────────────────────────────────────────────┤
│ Model Layer │
│ (SQLAlchemy ORM models) │
├─────────────────────────────────────────────────────┤
│ Database │
│ (PostgreSQL) │
└─────────────────────────────────────────────────────┘
- Request → Middleware (correlation ID, logging, rate limiting)
- Router → Route handler in
api/v1/endpoints/ - Dependencies → Auth, database session injection
- Service → Business logic in
services/ - Repository → Data access in
repositories/ - Response → Middleware → Client
All API responses follow a consistent format:
{
"success": true,
"data": { ... },
"message": "Operation successful",
"meta": {
"request_id": "uuid",
"timestamp": "2024-01-01T00:00:00Z"
}
}Error responses:
{
"success": false,
"error": "Error message",
"error_code": "VALIDATION_ERROR",
"details": { ... }
}# Run all tests
make test
# Run with coverage
make coverage
# Run specific test file
pytest tests/integration/test_users.py -v
# Run with output
pytest -s -vtests/
├── conftest.py # Shared fixtures
├── factories/ # Model factories (factory_boy)
│ └── user_factory.py
├── integration/ # API integration tests
│ ├── test_auth.py
│ ├── test_users.py
│ └── test_health.py
└── unit/ # Unit tests (add as needed)
import pytest
from httpx import AsyncClient
@pytest.mark.asyncio
async def test_create_user(client: AsyncClient, sample_user_data: dict):
response = await client.post("/api/v1/users/register", json=sample_user_data)
assert response.status_code == 201
assert response.json()["success"] is True# Create a new migration
make revision
# Enter message when prompted
# Run migrations
make migrate
# Or manually
alembic upgrade head
alembic downgrade -1Models inherit from BaseModel which provides:
- UUID primary key
created_at/updated_attimestamps- Soft delete support (
deleted_at)
from app.models.base import BaseModel
from sqlalchemy import String
from sqlalchemy.orm import Mapped, mapped_column
class MyModel(BaseModel):
__tablename__ = "my_models"
name: Mapped[str] = mapped_column(String(100), nullable=False)- Create Model in
app/models/ - Create Schemas in
app/schemas/ - Create Repository in
app/repositories/ - Create Service in
app/services/ - Create Endpoints in
app/api/v1/endpoints/ - Register Router in
app/api/v1/router.py - Create Migration:
make revision - Add Tests in
tests/
make help # Show all commands
make install # Install dependencies
make dev # Start development server
make test # Run tests
make coverage # Run tests with coverage
make lint # Run linters (ruff, mypy)
make format # Format code (black, ruff)
make migrate # Run database migrations
make revision # Create new migration
make docker-up # Start Docker services
make docker-down # Stop Docker services
make clean # Clean cached filesPre-commit hooks are configured for:
- Black - Code formatting
- Ruff - Linting
- MyPy - Type checking
- Bandit - Security checks
Install hooks:
pre-commit installRun manually:
pre-commit run --all-files# Add to pyproject.toml under dependencies, then:
pip install -e ".[dev]"Workers are configured in app/workers/celery_app.py.
# Start worker locally
make worker
# Start beat scheduler
make beat# app/workers/tasks/my_tasks.py
from celery import shared_task
@shared_task(bind=True, max_retries=3)
def my_background_task(self, user_id: str) -> bool:
# Task logic here
return Truefrom app.workers.tasks.my_tasks import my_background_task
# Async execution
my_background_task.delay(user_id)
# With options
my_background_task.apply_async(
args=[user_id],
countdown=60, # Delay 60 seconds
)docker build -t fastapi-app .
docker run -p 8000:8000 --env-file .env fastapi-app-
Environment Variables
- Set
APP_ENV=production - Use strong
JWT_SECRET_KEY - Configure proper
CORS_ORIGINS
- Set
-
Database
- Use connection pooling
- Run migrations before deployment
- Set up backups
-
Security
- Enable HTTPS
- Configure rate limiting
- Review CORS settings
-
Monitoring
- Use health endpoints for load balancers
- Set up log aggregation
- Configure error tracking (Sentry, etc.)
- Create a feature branch from
main - Make your changes
- Run tests:
make test - Run linters:
make lint - Submit a pull request
type(scope): description
Types: feat, fix, docs, style, refactor, test, chore
Example: feat(auth): add password reset functionality
- FastAPI Documentation
- SQLAlchemy 2.0 Documentation
- Pydantic v2 Documentation
- Celery Documentation
- Alembic Documentation
This project is licensed under the MIT License.