AI coding assistants still reach for FastAPI patterns from a few years ago: .dict(), orm_mode, session.query(), HTTPException raised deep inside service code, SQLite in tests. The code runs, but it isn't the code you'd write today.
Cursor's project rules fix most of this. A rule is a small .mdc file in .cursor/rules/ with a glob, so it loads only when you edit matching files:
---
description: "FastAPI routers, dependencies and Pydantic v2 schemas"
globs: src/app/**/router.py,src/app/**/schemas.py,src/app/**/deps.py
alwaysApply: false
---
- One APIRouter(prefix="/<plural-resource>") per feature ...
These are the 12 conventions that made the biggest difference for me.
model_validate, model_dump, ConfigDict, field_validator. Never .dict(), parse_obj, orm_mode, class Config or the v1 validator decorator.response_model`` status_code: 201 for create, 204 for delete. XCreate / XUpdate / XRead. ConfigDict(extra="forbid") so a sneaky "is_admin": true is rejected. Apply updates with model_dump(exclude_unset=True). Mapped[...], mapped_column(), select(). Never session.query() or declarative_base(). async with session.begin():. Repositories never commit. Use async_sessionmaker(expire_on_commit=False). lazy="raise". selectinload() or joinedload(), so there's no hidden IO in async code. MetaData(naming_convention=...) on your BaseAppError subclasses, never HTTPException.{"error": {"code": ..., "message": ...}}. get_settings()``os.environ elsewhere, and keep secrets as SecretStr. text(...).bindparams(). httpx.AsyncClient(transport=ASGITransport(app=app))``app.dependency_overrides after each test. No SQLite stand-in.
Drop rules like these into .cursor/rules/, one file per area, with globs that match your layout. For Claude Code, the same conventions work as a short CLAUDE.md at the repo root.
Disclosure: I made a FastAPI rules pack with these conventions written out as 7 scoped .mdc files plus a CLAUDE.md, and I sell it for $12 at codebaserules.com. Two of the files are a free download, no email needed. Everything above works without buying anything. I'd like to hear which of these you'd change.