FastAPI Enterprise Development - Modular Architecture
Enterprise-grade FastAPI with modular architecture: each business domain is an independent module with own database tables, cache namespace, routes, and migrations. Modern Python tooling (UV + pyproject.toml) for fast dependency management.
Quick Start
Initialize Project
# Create modular FastAPI project with UV python scripts/init_project.py --name my_api --auth keycloak --with-example-module # Result: # my_api/ ← Project name subdirectory # ├── src/ # │ ├── app.py ← Main application # │ ├── core/ ← Shared infrastructure (logging, DB, cache, module loader) # │ ├── middleware/ ← Conversation tracking, auth # │ └── routes/ ← Core routes (health, metrics) # ├── modules/ ← Independent modules # │ └── users/ ← Example: own routes, models, cache, migrations # ├── pyproject.toml ← UV configuration # ├── config/ ← YAML configurations # └── scripts/ ← Automation (create_module.py) # Install and run cd my_api uv sync # Install dependencies (10-100x faster than pip) cp .env.example .env uv run uvicorn src.app:app --reload
Create Independent Module
# Generate new module with complete structure uv run python scripts/create_module.py --name orders # Auto-creates: # modules/orders/ # ├── __init__.py ← Router export (auto-discovered) # ├── routes/ ← /api/v1/orders endpoints # ├── models/ ← SQLAlchemy models (own tables) # ├── schemas/ ← Pydantic validation # ├── services/ ← Business logic # ├── cache/ ← Module-specific cache (orders:* prefix) # ├── enums/ ← Module-specific enums # └── alembic/ ← Module-specific migrations
Minimal Modular App
# src/app.py
from fastapi import FastAPI
from src.core.config import settings
from src.core.logging import configure_logging
from src.core.cache import cache_manager
from src.core.module_loader import discover_modules
from src.middleware.conversation_middleware import ConversationMiddleware
# Configure logging (JSON/colored)
configure_logging(environment=settings.ENVIRONMENT)
app = FastAPI(title=settings.PROJECT_NAME)
app.add_middleware(ConversationMiddleware) # UUID tracking
@app.on_event("startup")
async def startup():
await cache_manager.connect() # Redis or memory
discover_modules(app) # Auto-register all modules
@app.get("/")
async def root():
return {"message": "Welcome"}
Core Capabilities
1. Modular Architecture ⭐
- •Independent Modules: Each module owns DB tables, cache keys, routes
- •Auto-Discovery: Modules in
modules/automatically registered - •Service-Layer Communication: Inter-module calls via services (no direct model imports)
- •Per-Module Migrations: Each module has own Alembic history
- •Enforced Boundaries:
modules.users.services.UserService✅ |from modules.users.models import User❌
2. Modern Python Tooling (UV + pyproject.toml) ⭐
- •UV: 10-100x faster than pip, Rust-based package manager
- •pyproject.toml: PEP 518/621 standard, replaces requirements.txt
- •uv.lock: Reproducible builds across environments
- •Project Subdirectory: All files in
my_api/(clean workspace) - •Export:
uv export --format requirements-txt > requirements.txtwhen needed
3. Flexible Caching ⭐
- •Redis (production): Distributed, persistent cache
- •Memory (development): Zero dependencies, instant setup
- •Module Namespaces:
users:123,orders:456(no collisions) - •Cache Decorators:
@cached(prefix="products", ttl=1800) - •Invalidation: Time-based (TTL), event-based (on update), pattern-based (
users:*)
4. Structured Logging (structlog)
- •JSON (production): Structured logs for aggregation (ELK, Splunk)
- •Colored Console (development): Human-readable with syntax highlighting
- •Conversation ID: UUID in all logs from
ConversationMiddleware - •Request/Response: Automatic logging with duration, status code
- •External APIs: Conversation ID propagated to downstream services
5. Type-Safe Configuration
- •pydantic-settings: OS environment variables with type validation
- •YAML:
config/development.ymlandconfig/production.yml - •Variable Substitution:
${DATABASE_PASSWORD}from environment - •CONFIG_ENV Switcher: Toggle between dev/prod configs
6. Async Database (SQLAlchemy 2.0)
- •Async: Full asyncio support with
asyncpgdriver - •PostgreSQL-Optimized: JSONB, arrays, full-text search
- •Per-Module Tables: Each module creates own tables
- •Central Session:
src/core/db.pysession factory used by all modules and Alembic
7. Per-Module Migrations (Alembic)
- •Independent Histories:
modules/users/alembic/,modules/orders/alembic/ - •Async Template: Configured for async SQLAlchemy
- •Auto-Generation:
alembic revision --autogenerate - •Run All:
python scripts/run_migrations.py --all
8. Central HTTP Client (httpx)
- •Async: Connection pooling, timeouts, retries
- •Conversation ID: Auto-propagated to
X-Conversation-IDheader - •YAML Configs: Base URLs from
config/*.yml - •Request Logging: All external API calls logged
9. Observability
- •Conversation Tracking: UUID from header/cookie, appears in all logs
- •Prometheus Metrics:
/metricsendpoint (request count, latency, errors) - •OpenTelemetry (optional): Distributed tracing (Jaeger, Zipkin)
- •Health Check:
/healthwith DB connectivity status
10. Authentication (Conditional)
AI MUST ASK: "Keycloak authentication (JWT from external IdP) or app-based RBAC (database-backed roles)?"
- •Keycloak: JWT validation, role extraction, Keycloak OpenID integration
- •App-based: Custom JWT, database roles/permissions, user management
- •Middleware: Token validation,
request.state.current_userinjection - •Role Decorators:
@requires_role("admin")
Automation Scripts
init_project.py
Initialize complete project with modular structure:
python scripts/init_project.py --name my_api --auth keycloak --with-example-module
create_module.py
Generate new independent module:
uv run python scripts/create_module.py --name products
create_endpoint.py
Add endpoint to existing module:
uv run python scripts/create_endpoint.py --module users --service auth --method post --path login
create_model.py
Create SQLAlchemy model + Alembic migration:
uv run python scripts/create_model.py --module products --name Product
validate_structure.py
Check project compliance:
uv run python scripts/validate_structure.py
Module Independence Rules
✅ DO:
- •Service Layer Communication:
from modules.users.services.user_service import UserService - •Module Namespaces:
users:cache:123,orders:cache:456 - •Own Tables: Each module creates own database tables
- •Own Migrations: Separate Alembic history per module
❌ DON'T:
- •Direct Model Imports:
from modules.users.models.user import User(use service instead) - •Shared Tables: No
ForeignKey("users.id")across modules (store as regular int) - •Cross-Module Cache: Don't access other module's cache directly
Resources
Reference Documentation
- •Project Structure - Directory layout, UV setup
- •Module Patterns - Independent module development
- •Cache Patterns - Redis/memory caching strategies
- •Routing Patterns - Auto-discovery, module loader
- •Logging Patterns - Structlog configuration
- •Configuration Patterns - pydantic-settings, YAML
- •Database Patterns - Async SQLAlchemy, CRUD
- •Alembic Setup - Per-module migrations
- •HTTPx Patterns - Central HTTP client
- •Observability Patterns - Conversation tracking, metrics
- •Authentication Patterns - Keycloak vs app-based
- •Clean Code Standards - DDD, no duplication
- •Error Handling Workflow - Systematic debugging
Automation Scripts
- •
scripts/init_project.py- Initialize complete project - •
scripts/create_module.py- Generate new module - •
scripts/create_endpoint.py- Add endpoint to module - •
scripts/create_model.py- Create model + migration - •
scripts/validate_structure.py- Check project compliance
Examples
- •Complete Usage Examples - 6 full examples (module creation, cache usage, auth, metrics, etc.)
License
MIT License - See LICENSE.txt for complete terms.