# FastAPI — Claude Code rules ## Tooling - Python 3.12+. `uv` or `pdm` for env/lock. No system pip. - Type hints everywhere — `mypy --strict` should pass. - Pydantic v2 (NOT v1). `model_dump()`, not `.dict()`. ## Endpoints - Async by default. Use `async def` for handlers unless the dependency is sync-only and short. - Pydantic models for request bodies AND response bodies. Use `response_model` so OpenAPI is accurate. - Path parameters via `Annotated[str, Path(...)]`. Query params via `Annotated[T, Query(...)]`. No bare default-value style. - HTTP errors via `HTTPException` with explicit `status_code` and `detail`. No bare `raise Exception(...)`. ## Project shape ``` app/ ├── main.py # FastAPI() instance + routers ├── routers/ │ └── *.py ├── schemas/ # pydantic models ├── services/ # business logic, framework-agnostic └── deps.py # FastAPI Depends() providers ``` ## Don't - Block the event loop with sync I/O inside an async handler. Use `asyncio.to_thread()` or move the call to a sync route. - Mutate global state across requests. Inject dependencies. - Skip response models — OpenAPI clients depend on them.