FastAPI
Typed Python APIs alongside Python integrations, data or AI libraries.
FastAPI · Pydantic · SQLAlchemy · Alembic
Complete guide (Markdown) · Structured record (JSON)
Original source review: 2026-10-10. Core guidance rechecked: 2026-10-13. Check scope. Dependency combinations and setup need project-specific qualification.
Use cases
- Typed JSON APIs
- Integration services
- HTTP endpoints for model or worker products
Choose it when
- API contracts and Python integrations matter more than built-in product/admin UI
- A separate frontend or service boundary already exists
Consider another path when
- The team mostly needs accounts, admin, forms and CRUD that Django supplies
- Blocking or CPU-intensive jobs would be run inside request event loops
Working practices
- Validate tokens and permissions in dependencies; Pydantic validation does not establish authorization.
- Keep blocking calls out of async request handling and configure database connection lifetimes.
- Commit and rehearse Alembic migrations. Use isolated databases for integration tests.
- Move durable work to operated workers; an in-process background task cannot guarantee recovery.
Tools by job
Packaging and environments: uv + pyproject.toml + committed uv.lock
One project entry point for dependencies, Python selection, execution and reproducible sync.
Pin a compatible Python minor and resolve actual package versions at implementation; do not hand-edit uv.lock. Keep environments and caches in a local development workspace.
Lint and format: Ruff
Fast lint and formatting feedback with one configuration.
Ruff does not replace static typing, tests, authorization checks or runtime validation.
Static typing: mypy
Explicit checks on application boundaries with a conservative established checker.
Configure strictness and third-party stubs; unchecked Any and untyped functions reduce coverage. No checker performance comparison was run.
Testing: pytest + HTTPX / FastAPI TestClient
Test contract failures, auth and integration boundaries.
Run startup/shutdown lifespan when relevant; include PostgreSQL and external-service fault tests.
Database and migrations: PostgreSQL + SQLAlchemy + Psycopg + Alembic
Explicit transactions and versioned relational changes.
Session per thread / AsyncSession per task. Review generated migrations, especially renames and data changes; a passing migration check does not prove production lock safety.
Validation: Pydantic request/response models; strict validation where coercion is unsafe
Typed schemas clarify external contracts and generated documentation.
Coercion is configurable; schema validity is not authorization or business correctness. Avoid returning unrestricted ORM objects.
Authentication: Existing OIDC provider; validate access tokens and authorization in dependencies
Keep identity lifecycle with its owner while enforcing permissions at the API.
Choose and verify token-validation integration at implementation. FastAPI's JWT tutorial is not a complete identity system; issuer, audience, expiry and permissions need tests.
Jobs: Separate Celery workers for queued jobs
Separate request latency from heavy or retried work.
BackgroundTasks does not establish durable execution. Make job effects idempotent and set retry/deadline limits.
Long-running durable agents: Temporal Python SDK when recovery across restarts is required
Persisted workflow orchestration and separate worker processes suit retries, pauses and human waits.
Adds a service and operational cost. Keep external I/O in activities, make side effects idempotent, test replay and cancellation; no end-to-end integration was run.
Serving and deployment: FastAPI standard CLI / Uvicorn in a container
Official deployment path with explicit process and container choices.
Build from a supported base rather than deprecated framework images; choose process count to match deployment/memory, and run schema migration once per release.
Application logging: Python logging with configured handlers
Shared standard logging captures application and dependency diagnostics
Configure logging at entry point, redact credentials and add request/job IDs, duration and failure context. Persist logs on the execution platform; metrics/tracing backend is a separate operational choice.
Bounded external-call retries: Tenacity only for retryable transient failures
Explicit stop/wait/filter rules support controlled retries
Install tenacity; set attempt/deadline limits, jitter and exception filters. The bare decorator retries forever without delay; do not stack retries with SDK/worker retries or repeat non-idempotent effects without keys.
Uploads: FastAPI UploadFile
Spooling file interface avoids eagerly materializing all content in application memory
Install python-multipart; enforce request/file limits and authorization, stream to durable storage and clean partial writes. Multipart parsing does not establish file safety.
Realtime transport: FastAPI WebSocket endpoints
Native ASGI endpoint support fits connected API clients
Authorize handshake/messages; bound per-client queues, handle disconnect and share state through an external service for replicas. In-memory tutorial connection lists are not multi-process state.
Object storage: Boto3 S3 client when durable objects are required
Official SDK supports file transfer to S3
Install boto3 only for S3-backed work; use platform credentials, private keys and bounded transfers. Boto3 is synchronous: keep blocking transfers out of an async event loop; verify alternative provider compatibility.
Build with the stack’s strengths
Architecture and developer workflow.
FastAPI exposes Python type-annotated HTTP operations and dependency boundaries. It supports synchronous and async handlers; the choice depends on whether called libraries support await. Recommendation: keep request models distinct from persistence operations and explicitly select identity, durable jobs, database migrations and distributed messaging instead of assuming the API framework provides an integrated monolith.
Version scope: Current FastAPI online guides fetched 11 October 2026; these pages do not pin an application package release. SQLAlchemy 2.0 documentation, Alembic 1.20.0 documentation and Celery 5.6.3 reviewed. Pin actual Python/FastAPI/Pydantic/Starlette/database-driver versions before implementation. · Reviewed 2026-10-11
Architecture boundaries
- Use async handlers with awaitable I/O, or normal def handlers for blocking libraries as the guide explains. Recommendation: keep CPU-heavy or durable work behind a deliberate worker boundary; adding async syntax does not change its durability or CPU execution model.
- SQLAlchemy Sessions are mutable transaction state and cannot be shared across concurrent tasks/threads. Recommendation: scope a Session to its operation, keep the engine/pool separate and use reviewed Alembic revisions for schema evolution.
- FastAPI lifespan manages startup/shutdown resources. Multiple worker processes are a deployment choice; recommendation: treat in-memory connections/caches as worker-local and keep one external scheduler and migration owner.
Tools and feedback
- For a configured application, adapt fastapi run --workers 4 main.py or uvicorn main:app --workers 4 from the deployment guide; replace module and worker count for the actual host/container topology. The example is a recipe, not a capacity recommendation.
- For a configured SQLAlchemy/Alembic application, use alembic revision -m "Add a column", review upgrade/downgrade operations, then alembic upgrade head in a disposable database; alembic current and alembic history show recorded state.
- Use FastAPI TestClient and pytest for HTTP contract tests. Recommendation: add real database/worker tests for transaction and retry boundaries, plus WebSocket tests across the intended multi-process topology.
- Recommendation: initialize shared process resources through the lifespan context and create independent database sessions for concurrent operations. Validate selected sync/async client usage and cleanup on shutdown before rollout.
Translations to avoid
- Avoid using BackgroundTasks as a durable queue replacement: it executes work associated with the application process, while the guide recommends larger worker tools such as Celery for work that belongs in multiple processes/servers. Recommendation: qualify crash/retry behavior explicitly.
- Avoid copying the tutorial’s in-memory WebSocket connection list into a multi-worker product; the docs explicitly say it works only in one running process.
- Avoid sharing one SQLAlchemy Session among requests/tasks or moving blocking library calls unchanged inside async handlers; the documented concurrency boundaries differ.
- Avoid treating a JWT tutorial as a complete identity migration. Recommendation: retain existing identity authority until issuer, account mapping, validation, expiry and revocation are designed. Starlette SessionMiddleware signs readable cookie contents; signing is not confidentiality.
For an existing application
Keep the contracts while you change the stack.
These are documented options and proposed checks. Inspect the actual source application before adopting a transition.
Data and schema
Inspect the source
Inventory schema, primary IDs, SQL value/constraint semantics and existing transaction ownership. The old application may use an ORM with callbacks absent from the target service.
During coexistence
Recommendation: keep one writer and migration runner; start with read-only target endpoints or a bounded domain operation. Preserve additive schema and qualify ORM/session behavior before transferring writes.
Target design
SQLAlchemy 2.0 Sessions scoped to operations, with reviewed Alembic upgrade/downgrade revisions and the selected PostgreSQL driver. Recommendation: keep transaction and external delivery boundaries explicit.
Rollback
Recommendation: restore the old writer while preserving backward-readable schema; use downgrade only for a rehearsed reversible change and reconcile accepted new data.
Benefits and prerequisites
Recommendation: explicit sessions and migrations expose the persistence boundary to review.
Requires: Qualified schema mapping, operation-scoped sessions and one writer owner.
Tradeoffs: FastAPI does not remove ORM/migration choices; deleting data cannot be undone by traffic rollback.
Checks before transfer
- Create through each allowed writer and read through both runtimes; compare IDs, timestamps/null values and constraint failures.
- Run concurrent requests with separate sessions and fail one transaction; no other request’s changes or Session state may leak.
- Apply a reviewed revision to a disposable restored database and verify both deployed versions still read new writes.
Jobs and schedules
Inspect the source
Record old task name/class, serialized arguments, broker, retries/acknowledgements, schedule ownership and every backlog state. BackgroundTasks and a broker-backed worker are different execution contracts.
During coexistence
Recommendation: retain old consumers and isolate new categories behind a versioned task interface. Use configured Celery or another separately qualified persistent system when restart recovery matters; keep one schedule owner and a recoverable domain-to-broker handoff.
Target design
An explicitly selected durable worker/broker composition with business idempotency. Small best-effort same-process tasks may use BackgroundTasks only when their documented process boundary fits the requirement.
Rollback
Recommendation: stop new task production, retain consumers for accepted payload versions and reconcile external effects before restoring old routing.
Benefits and prerequisites
Recommendation: durable work can move independently of the HTTP service.
Requires: Selected broker/worker configuration, tested payloads and explicit idempotency/recovery policy.
Tradeoffs: The broker and worker add operated components; returning HTTP success before enqueue acceptance must have a deliberate contract.
Checks before transfer
- Enqueue while the worker is stopped, restart it and verify the intended completion/failure result.
- Crash after an external effect before acknowledgement and verify retry is safe; test broker outage during a domain write.
- Reconcile delayed/retry/failed/running tasks and verify the old and new schedulers never both produce the category.
Identity and authorization
Inspect the source
Capture the source identity authority, token/cookie format, issuer/audience rules, account IDs, expiration and revocation. The FastAPI OAuth2/JWT guide is a concrete example, not proof of compatibility with existing sessions.
During coexistence
Recommendation: retain the existing identity authority through qualified token verification or session exchange. Move resource authorization with the domain operation, and keep cookie scope/CSRF behavior explicit when using browser cookies.
Target design
Selected OAuth2/token or browser-session implementation with deliberate account mapping and authorization. If using Starlette SessionMiddleware, cookie data is signed and readable; use https_only and appropriate scope settings for the selected deployment.
Rollback
Recommendation: preserve account mapping and old credential/exchange support without reversing revocations; return routing only when validation remains compatible.
Benefits and prerequisites
Recommendation: a shared identity authority can preserve access across service boundaries.
Requires: Qualified token/session validation and common revocation policy.
Tradeoffs: Bearer expiry and server-side revocation are distinct design choices; readable signed cookies must not contain secrets.
Checks before transfer
- Accept a valid source credential and reject modified/expired credentials and a valid credential for another tenant’s protected record.
- Logout/revoke and confirm both old/new paths follow the agreed policy, including an existing WebSocket connection.
- Inspect the selected cookie contents and transport flags; no secret should be exposed by a signed-but-readable session.
Realtime transport
Inspect the source
Capture the old client protocol, message envelope, connection authentication, subscription scopes and recovery requirements. FastAPI provides WebSocket handlers; its in-memory chat example is explicitly single-process.
During coexistence
Recommendation: retain the old endpoint for old clients, bridge versioned domain events and route a stable user/room cohort including reconnects. Keep fanout in a separately qualified shared system when multiple worker processes must reach the same recipients.
Target design
FastAPI WebSocket handlers with explicit shared fanout and persisted domain-state/cursor recovery when required. No specific broker/client combination is integration-qualified by this research.
Rollback
Recommendation: preserve old endpoint/message compatibility through reconnects; return the cohort and reconcile current domain state instead of reissuing effects.
Benefits and prerequisites
Recommendation: an API service can take ownership of a realtime boundary incrementally.
Requires: Matching message/client protocol, subscription authorization and a tested multi-worker fanout implementation.
Tradeoffs: Connection lists remain worker-local; selecting a shared broker does not itself provide catch-up or protocol compatibility.
Checks before transfer
- Connect clients to different workers, commit one domain event and verify all authorized recipients converge.
- Restart the worker containing a connection, reconnect and recover missed state; test a revoked identity attempting to rejoin.
Caching and shared state
Inspect the source
List reconstructible values and representation/TTL/invalidation separately from identities, jobs, counters and locks. Multiple application workers have distinct in-memory resource ownership.
During coexistence
Recommendation: keep the existing shared store for coordination; use versioned keys for new representations. Move only disposable values to local caching when per-worker staleness and rebuilding are explicitly accepted.
Target design
A selected shared cache accessed with a qualified client such as redis-py, or an explicitly bounded local cache. Recommendation: match sync/async client usage to the handler and manage process resource lifetime deliberately.
Rollback
Recommendation: restore old key/backend routing and repopulate from domain data; preserve shared coordination ownership throughout.
Benefits and prerequisites
Recommendation: cache choices can evolve without transferring domain ownership.
Requires: Reconstructible values, explicit invalidation and a complete list of shared-store uses.
Tradeoffs: Local values diverge across workers; removing Redis requires separately retiring sessions/queues/coordination, not merely replacing cached reads.
Checks before transfer
- Warm two workers, update the source and verify required invalidation/staleness across both.
- Restart one worker or evict its dedicated cache and verify reconstruction without losing identity or queued work.
- Make the shared cache unavailable and verify the agreed failure/fallback behavior rather than silently accepting stale authorization.
Delivery and recovery
Inspect the source
Inventory API workers, startup resources, database migration runner, durable workers, external scheduler and shared fanout/cache. Worker replication and lifespan resources are not a singleton schedule mechanism.
During coexistence
Recommendation: keep one schema runner and logical schedule owner while both services operate. Initialize per-process resources deliberately and transfer traffic by a stable domain/user cohort.
Target design
An explicit FastAPI/Uvicorn process/container deployment, lifespan cleanup, separate durable workers and monitored dependency boundaries. Recommendation: record actual worker count and deployment settings instead of inheriting tutorial values.
Rollback
Recommendation: preserve the old release and compatible schema, transfer role ownership before restoring traffic, and reconcile work accepted by the new service.
Benefits and prerequisites
Recommendation: process/resource ownership makes multi-worker behavior reviewable.
Requires: Named migration/schedule owners, configured shutdown and tested dependency failure behavior.
Tradeoffs: More workers multiply process-local resources; successful HTTP startup cannot qualify broker, identity or restore behavior.
Checks before transfer
- Start the intended multi-worker deployment against disposable restored data; exercise authenticated HTTP, one task and cross-worker realtime delivery.
- Terminate a worker during active work, verify shutdown/restart behavior and confirm no extra scheduler or migration runner starts.
Setup
- In a new local source directory: uv init; pin a compatible Python minor; uv add 'fastapi[standard]' sqlalchemy 'psycopg[binary]' alembic pydantic-settings
- uv add --dev ruff mypy pytest httpx
- Create an importable app package with app/main.py exporting app = FastAPI(), request/response models and a health endpoint.
- uv run alembic init migrations; configure environment-based connection URL and target_metadata. Implement per-request/task sessions and domain transaction boundaries.
- uv run alembic revision --autogenerate -m 'initial schema'; manually review, then uv run alembic upgrade head against the development DB.
- Configure the selected identity provider and token verification; implement tenant/object authorization before adding protected endpoints.
- Develop with uv run fastapi dev app/main.py. Package a release with uv sync --locked --no-dev and an explicit production start command; add workers separately when needed.
Verification
Run these in the configured application; they are instructions, not recorded passes.
uv sync --locked uv run ruff check . uv run ruff format --check . uv run mypy app uv run pytest uv run alembic check uv run alembic current
Open questions
- Which identity provider, token validation and tenant authorization model apply?
- Does workload justify async database access, or is synchronous I/O simpler?
- Which host/replica model, upload storage, realtime and worker guarantees apply?
Sources
- uv projects
- Ruff installation
- mypy getting started
- ty type checking
- pytest getting started
- FastAPI containers
- SQLAlchemy session basics
- Alembic autogeneration
- Pydantic strict mode
- FastAPI JWT tutorial
- Authlib OAuth web clients
- FastAPI background tasks
- Celery tasks
- Temporal Python SDK
- uv Docker
- FastAPI concurrency
- Python logging
- Tenacity documentation
- FastAPI request files
- FastAPI WebSockets
- Boto3 uploads