ipIterPrompt

CLAUDE.md for Python APIs

FastAPI/Django-ready CLAUDE.md with typing, testing, and migration guardrails.

iterpromptUpdated 2026-06-243,080 copies

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

  1. 1Copy to your repo root as CLAUDE.md, adjust to your stack (swap uv for poetry, FastAPI for Django as needed).
  2. 2The database section is the most valuable part — migration accidents are agents' most expensive Python failure mode.
  3. 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.

Related