CLAUDE.md for Python APIs
FastAPI/Django-ready CLAUDE.md with typing, testing, and migration guardrails.
A CLAUDE.md template for Python API services: environment and command setup, typing and error-handling standards, database migration safety rules, and test conventions. Written for FastAPI but includes the Django variants where they differ.
The template
# CLAUDE.md ## Project [Service name] — [one sentence]. FastAPI + SQLAlchemy + Postgres. Python 3.12, managed with uv. ## Commands ```bash uv sync # install deps uv run uvicorn app.main:app --reload # dev server uv run pytest # tests — ALWAYS run affected tests before finishing uv run pytest tests/test_x.py -k name # single test uv run ruff check --fix . && uv run ruff format . # lint + format uv run alembic upgrade head # apply migrations ``` ## Architecture - `app/routers/` — HTTP layer only: parsing, auth deps, response shaping. No business logic - `app/services/` — business logic, pure functions where possible - `app/models/` — SQLAlchemy models; `app/schemas/` — Pydantic request/response schemas - Never let a SQLAlchemy model cross the API boundary — always map to a schema ## Rules ### Code standards - Full type hints on all new functions; `mypy --strict` must pass on changed files - Raise domain exceptions from services; map to HTTP codes only in routers - No bare `except:`; catch specific exceptions and preserve the chain (`raise ... from e`) - Use dependency injection (FastAPI Depends) for db sessions and auth — never module-level sessions ### Database - Schema changes ONLY via Alembic migrations — never edit models without generating one - Migrations must be reversible; write the downgrade - No data migrations mixed into schema migrations — separate revisions - New columns on large tables: nullable first, backfill separately, then constrain ### Testing - New endpoints need: happy path, auth failure, validation failure tests minimum - Use factories (factory_boy), not fixtures with hardcoded IDs - Tests hit a real Postgres (docker compose), not SQLite — dialect differences bite ## Don't - Don't add dependencies without asking - Don't touch `app/legacy/` — it's being strangled; add new code in the new structure - Don't log request bodies (PII) — log IDs and metadata ## Verification Definition of done: ruff clean, mypy clean on changed files, affected tests pass, new migration applies AND downgrades cleanly.
How to use
- 1Copy to your repo root as CLAUDE.md, adjust to your stack (swap uv for poetry, FastAPI for Django as needed).
- 2The database section is the most valuable part — migration accidents are agents' most expensive Python failure mode.
- 3Mark your own no-go zones like the legacy directory example; agents respect explicit boundaries well.
Examples
Migration safety in action
Input
Agent asked to add a `preferences` JSON column to the users table (8M rows).
Output
Following the rules: generates an Alembic revision adding the column as nullable (no default — avoids a full table rewrite), writes the downgrade, notes that the backfill should be a separate revision, and runs upgrade+downgrade against the dev database to verify both directions.
Pro tips
- The 'nullable first, backfill, then constrain' rule alone prevents the most common self-inflicted outage.
Frequently asked questions
Django instead of FastAPI — what changes?+
Swap the commands block (manage.py runserver, migrate, makemigrations), replace the routers/services split with views/services, and keep everything else — the typing, testing, and migration rules transfer directly.