stack.menu

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

Choose it when

Consider another path when

Working practices

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

Tools and feedback

Translations to avoid

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.

Read the migration workflow →

Setup

  1. In a new local source directory: uv init; pin a compatible Python minor; uv add 'fastapi[standard]' sqlalchemy 'psycopg[binary]' alembic pydantic-settings
  2. uv add --dev ruff mypy pytest httpx
  3. Create an importable app package with app/main.py exporting app = FastAPI(), request/response models and a health endpoint.
  4. uv run alembic init migrations; configure environment-based connection URL and target_metadata. Implement per-request/task sessions and domain transaction boundaries.
  5. uv run alembic revision --autogenerate -m 'initial schema'; manually review, then uv run alembic upgrade head against the development DB.
  6. Configure the selected identity provider and token verification; implement tenant/object authorization before adding protected endpoints.
  7. 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

Sources