Skip to content

theebruv/fastapi-template

Repository files navigation

FastAPI Production Backend Template

A comprehensive, production-ready FastAPI backend template with all batteries included for scalable web applications.

✨ Features

  • 🔐 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

🚀 Quick Start

Prerequisites

  • Python 3.11+
  • PostgreSQL 15+
  • Redis 7+
  • Docker & Docker Compose (optional, for containerized development)

Option 1: Local 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

Option 2: Docker Development

# Start all services
docker-compose up -d

# View logs
docker-compose logs -f app

# Stop services
docker-compose down

Accessing the Application


📁 Project Structure

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

Configuration is managed through environment variables using Pydantic Settings.

Environment Variables

Create a .env file from the example:

cp .env.example .env

Key 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.


🔌 API Endpoints

Authentication

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

Users

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)

Health Checks

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

🏗️ Architecture

Layered Architecture

┌─────────────────────────────────────────────────────┐
│                    API Layer                        │
│              (endpoints, router)                    │
├─────────────────────────────────────────────────────┤
│                  Service Layer                      │
│            (business logic, validation)             │
├─────────────────────────────────────────────────────┤
│                Repository Layer                     │
│              (data access, queries)                 │
├─────────────────────────────────────────────────────┤
│                  Model Layer                        │
│           (SQLAlchemy ORM models)                   │
├─────────────────────────────────────────────────────┤
│                   Database                          │
│                 (PostgreSQL)                        │
└─────────────────────────────────────────────────────┘

Request Flow

  1. Request → Middleware (correlation ID, logging, rate limiting)
  2. Router → Route handler in api/v1/endpoints/
  3. Dependencies → Auth, database session injection
  4. Service → Business logic in services/
  5. Repository → Data access in repositories/
  6. Response → Middleware → Client

Response Envelope

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": { ... }
}

🧪 Testing

Running Tests

# 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 -v

Test Structure

tests/
├── 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)

Writing Tests

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

🗄️ Database

Migrations

# Create a new migration
make revision
# Enter message when prompted

# Run migrations
make migrate

# Or manually
alembic upgrade head
alembic downgrade -1

Models

Models inherit from BaseModel which provides:

  • UUID primary key
  • created_at / updated_at timestamps
  • 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)

Adding a New Entity

  1. Create Model in app/models/
  2. Create Schemas in app/schemas/
  3. Create Repository in app/repositories/
  4. Create Service in app/services/
  5. Create Endpoints in app/api/v1/endpoints/
  6. Register Router in app/api/v1/router.py
  7. Create Migration: make revision
  8. Add Tests in tests/

🔧 Development

Available Make Commands

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 files

Code Quality

Pre-commit hooks are configured for:

  • Black - Code formatting
  • Ruff - Linting
  • MyPy - Type checking
  • Bandit - Security checks

Install hooks:

pre-commit install

Run manually:

pre-commit run --all-files

Adding Dependencies

# Add to pyproject.toml under dependencies, then:
pip install -e ".[dev]"

📦 Background Tasks

Celery Configuration

Workers are configured in app/workers/celery_app.py.

# Start worker locally
make worker

# Start beat scheduler
make beat

Creating Tasks

# 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 True

Calling Tasks

from 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
)

🚢 Deployment

Docker Build

docker build -t fastapi-app .
docker run -p 8000:8000 --env-file .env fastapi-app

Production Considerations

  1. Environment Variables

    • Set APP_ENV=production
    • Use strong JWT_SECRET_KEY
    • Configure proper CORS_ORIGINS
  2. Database

    • Use connection pooling
    • Run migrations before deployment
    • Set up backups
  3. Security

    • Enable HTTPS
    • Configure rate limiting
    • Review CORS settings
  4. Monitoring

    • Use health endpoints for load balancers
    • Set up log aggregation
    • Configure error tracking (Sentry, etc.)

🤝 Contributing

  1. Create a feature branch from main
  2. Make your changes
  3. Run tests: make test
  4. Run linters: make lint
  5. Submit a pull request

Commit Message Format

type(scope): description

Types: feat, fix, docs, style, refactor, test, chore

Example: feat(auth): add password reset functionality


📚 Additional Resources


📄 License

This project is licensed under the MIT License.

About

No description, website, or topics provided.

Resources

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages