FastAPI + SQLAlchemy + pytest rules for AI coding agents
Full stack: Python + FastAPI + SQLAlchemy 2 + Alembic + pytest + Docker
Ready-to-commit rules for Python + FastAPI + SQLAlchemy 2 + Alembic + pytest + Docker in every major format: AGENTS.md (Codex, Cursor, Copilot), CLAUDE.md (Claude Code), Cursor .mdc project rules, legacy .cursorrules, Copilot instructions, Windsurf rules and GEMINI.md. A production-style Python API: FastAPI, SQLAlchemy 2 and Alembic, tested with pytest.
Last reviewed 2026-10-21 · Customise in the generator · Raw: AGENTS.md, CLAUDE.md
Agents mix legacy `session.query()` with 2.0 style and block the event loop with sync calls in `async def`.
Generated files
# AGENTS.md - this project
Instructions for AI coding agents working in this repository.
## Project
A Python + FastAPI + SQLAlchemy 2 + Alembic + pytest + Docker project.
Stack: Python + FastAPI, SQLAlchemy 2 + Alembic, pytest, Docker.
## Commands
- Install deps: `uv sync`
- Dev server: `uv run fastapi dev`
- Lint and format: `uv run ruff check . && uv run ruff format .`
- Tests: `uv run pytest`
- New migration: `uv run alembic revision --autogenerate -m "<change>"`
- Apply migrations: `uv run alembic upgrade head`
- Tests: `uv run pytest -q`
- Local services: `docker compose up -d`
## Project structure
- `app/main.py` creates the app; one `APIRouter` per domain in `app/routers/`.
- Pydantic schemas in `app/schemas/`, business logic in `app/services/`.
## How to work in this repo
- Read the relevant files before editing. Follow the patterns already in the codebase over these generic rules.
- Make the smallest change that solves the task. Do not refactor or reformat unrelated code.
- Before saying a task is done, run the type-check, lint and tests listed under Commands and fix what you broke.
- If requirements are ambiguous, ask one clear question instead of guessing.
- Never commit secrets, API keys or `.env` files. Use env vars and keep `.env.example` up to date.
- Do not add a new dependency when the standard library or an existing dependency already covers it.
- Ask before adding, removing or upgrading any dependency.
- Ask before changing database schemas, auth, payments or CI configuration.
- Never delete files, drop data or run destructive commands (`rm -rf`, `git push --force`, `DROP TABLE`) without explicit approval.
- Keep each change under ~200 changed lines where possible; split larger work into steps.
## Python + FastAPI
- Type-hint every function. Use `Annotated[..., Depends(...)]` for dependencies.
- Request and response bodies are Pydantic v2 models; set `response_model` so output is filtered.
- Use `async def` only when the endpoint awaits async I/O. Blocking libraries go in plain `def` endpoints.
- Inject DB sessions, settings and the current user with dependencies, not globals.
- Load settings with `pydantic-settings` from env vars.
- Raise `HTTPException` with a clear `detail` for expected errors.
- Manage dependencies with `uv add <pkg>`; do not hand-edit lock files.
## SQLAlchemy 2 + Alembic
- Use SQLAlchemy 2.0 style: `DeclarativeBase`, `Mapped[...]`, `mapped_column()`, and `select()` statements. No legacy `session.query()`.
- Every schema change gets an Alembic migration; review autogenerated migrations before applying.
- Scope one session per request (via a dependency) and never share sessions across threads.
- Load relationships deliberately with `selectinload` / `joinedload` to avoid N+1 queries.
## pytest
- Tests live in `tests/` named `test_*.py`. Use plain `assert`.
- Share setup with fixtures in `conftest.py`; use `@pytest.mark.parametrize` for input tables.
- Mock external services (HTTP, LLM APIs, payment providers); tests must not hit the network.
- Every bug fix adds a regression test.
## Docker
- Use multi-stage builds and slim, pinned base images.
- Run the app as a non-root user in the final image.
- Keep a `.dockerignore` that excludes `.git`, `node_modules`, `.env` and build output.
- Never bake secrets into images; pass them at runtime.
## Reference docs
- [FastAPI docs](https://fastapi.tiangolo.com)
- [SQLAlchemy docs](https://docs.sqlalchemy.org/en/20/)
- [pytest docs](https://docs.pytest.org)
- [Dockerfile best practices](https://docs.docker.com/build/building/best-practices/)
# CLAUDE.md - this project
Project instructions for Claude Code.
## Project
A Python + FastAPI + SQLAlchemy 2 + Alembic + pytest + Docker project.
Stack: Python + FastAPI, SQLAlchemy 2 + Alembic, pytest, Docker.
## Commands
- Install deps: `uv sync`
- Dev server: `uv run fastapi dev`
- Lint and format: `uv run ruff check . && uv run ruff format .`
- Tests: `uv run pytest`
- New migration: `uv run alembic revision --autogenerate -m "<change>"`
- Apply migrations: `uv run alembic upgrade head`
- Tests: `uv run pytest -q`
- Local services: `docker compose up -d`
## Project structure
- `app/main.py` creates the app; one `APIRouter` per domain in `app/routers/`.
- Pydantic schemas in `app/schemas/`, business logic in `app/services/`.
## How to work in this repo
- Read the relevant files before editing. Follow the patterns already in the codebase over these generic rules.
- Make the smallest change that solves the task. Do not refactor or reformat unrelated code.
- Before saying a task is done, run the type-check, lint and tests listed under Commands and fix what you broke.
- If requirements are ambiguous, ask one clear question instead of guessing.
- Never commit secrets, API keys or `.env` files. Use env vars and keep `.env.example` up to date.
- Do not add a new dependency when the standard library or an existing dependency already covers it.
- Ask before adding, removing or upgrading any dependency.
- Ask before changing database schemas, auth, payments or CI configuration.
- Never delete files, drop data or run destructive commands (`rm -rf`, `git push --force`, `DROP TABLE`) without explicit approval.
- Keep each change under ~200 changed lines where possible; split larger work into steps.
## Python + FastAPI
- Type-hint every function. Use `Annotated[..., Depends(...)]` for dependencies.
- Request and response bodies are Pydantic v2 models; set `response_model` so output is filtered.
- Use `async def` only when the endpoint awaits async I/O. Blocking libraries go in plain `def` endpoints.
- Inject DB sessions, settings and the current user with dependencies, not globals.
- Load settings with `pydantic-settings` from env vars.
- Raise `HTTPException` with a clear `detail` for expected errors.
- Manage dependencies with `uv add <pkg>`; do not hand-edit lock files.
## SQLAlchemy 2 + Alembic
- Use SQLAlchemy 2.0 style: `DeclarativeBase`, `Mapped[...]`, `mapped_column()`, and `select()` statements. No legacy `session.query()`.
- Every schema change gets an Alembic migration; review autogenerated migrations before applying.
- Scope one session per request (via a dependency) and never share sessions across threads.
- Load relationships deliberately with `selectinload` / `joinedload` to avoid N+1 queries.
## pytest
- Tests live in `tests/` named `test_*.py`. Use plain `assert`.
- Share setup with fixtures in `conftest.py`; use `@pytest.mark.parametrize` for input tables.
- Mock external services (HTTP, LLM APIs, payment providers); tests must not hit the network.
- Every bug fix adds a regression test.
## Docker
- Use multi-stage builds and slim, pinned base images.
- Run the app as a non-root user in the final image.
- Keep a `.dockerignore` that excludes `.git`, `node_modules`, `.env` and build output.
- Never bake secrets into images; pass them at runtime.
## Reference docs
- [FastAPI docs](https://fastapi.tiangolo.com)
- [SQLAlchemy docs](https://docs.sqlalchemy.org/en/20/)
- [pytest docs](https://docs.pytest.org)
- [Dockerfile best practices](https://docs.docker.com/build/building/best-practices/)
---
description: "Core rules for this project"
alwaysApply: true
---
# this project
A Python + FastAPI + SQLAlchemy 2 + Alembic + pytest + Docker project.
Stack: Python + FastAPI, SQLAlchemy 2 + Alembic, pytest, Docker.
## Commands
- Install deps: `uv sync`
- Dev server: `uv run fastapi dev`
- Lint and format: `uv run ruff check . && uv run ruff format .`
- Tests: `uv run pytest`
- New migration: `uv run alembic revision --autogenerate -m "<change>"`
- Apply migrations: `uv run alembic upgrade head`
- Tests: `uv run pytest -q`
- Local services: `docker compose up -d`
## How to work in this repo
- Read the relevant files before editing. Follow the patterns already in the codebase over these generic rules.
- Make the smallest change that solves the task. Do not refactor or reformat unrelated code.
- Before saying a task is done, run the type-check, lint and tests listed under Commands and fix what you broke.
- If requirements are ambiguous, ask one clear question instead of guessing.
- Never commit secrets, API keys or `.env` files. Use env vars and keep `.env.example` up to date.
- Do not add a new dependency when the standard library or an existing dependency already covers it.
- Ask before adding, removing or upgrading any dependency.
- Ask before changing database schemas, auth, payments or CI configuration.
- Never delete files, drop data or run destructive commands (`rm -rf`, `git push --force`, `DROP TABLE`) without explicit approval.
- Keep each change under ~200 changed lines where possible; split larger work into steps.
---
description: "Python + FastAPI conventions: FastAPI service with Pydantic v2 and uv."
globs: **/*.py
alwaysApply: false
---
# Python + FastAPI
- Type-hint every function. Use `Annotated[..., Depends(...)]` for dependencies.
- Request and response bodies are Pydantic v2 models; set `response_model` so output is filtered.
- Use `async def` only when the endpoint awaits async I/O. Blocking libraries go in plain `def` endpoints.
- Inject DB sessions, settings and the current user with dependencies, not globals.
- Load settings with `pydantic-settings` from env vars.
- Raise `HTTPException` with a clear `detail` for expected errors.
- Manage dependencies with `uv add <pkg>`; do not hand-edit lock files.
Docs: https://fastapi.tiangolo.com
---
description: "SQLAlchemy 2 + Alembic conventions: SQLAlchemy 2.0 ORM with Alembic migrations."
globs: **/models/**/*.py, alembic/**
alwaysApply: false
---
# SQLAlchemy 2 + Alembic
- Use SQLAlchemy 2.0 style: `DeclarativeBase`, `Mapped[...]`, `mapped_column()`, and `select()` statements. No legacy `session.query()`.
- Every schema change gets an Alembic migration; review autogenerated migrations before applying.
- Scope one session per request (via a dependency) and never share sessions across threads.
- Load relationships deliberately with `selectinload` / `joinedload` to avoid N+1 queries.
Docs: https://docs.sqlalchemy.org/en/20/
---
description: "pytest conventions: Python tests with pytest."
globs: tests/**/*.py, **/test_*.py
alwaysApply: false
---
# pytest
- Tests live in `tests/` named `test_*.py`. Use plain `assert`.
- Share setup with fixtures in `conftest.py`; use `@pytest.mark.parametrize` for input tables.
- Mock external services (HTTP, LLM APIs, payment providers); tests must not hit the network.
- Every bug fix adds a regression test.
Docs: https://docs.pytest.org
---
description: "Docker conventions: Containerised builds and local services with Docker."
globs: Dockerfile, **/Dockerfile, compose.yaml, docker-compose.yml, .dockerignore
alwaysApply: false
---
# Docker
- Use multi-stage builds and slim, pinned base images.
- Run the app as a non-root user in the final image.
- Keep a `.dockerignore` that excludes `.git`, `node_modules`, `.env` and build output.
- Never bake secrets into images; pass them at runtime.
Docs: https://docs.docker.com/build/building/best-practices/
# Cursor rules - this project
You are an expert Python + FastAPI, SQLAlchemy 2 + Alembic, pytest, Docker engineer working on this codebase. Follow these rules.
## Project
A Python + FastAPI + SQLAlchemy 2 + Alembic + pytest + Docker project.
Stack: Python + FastAPI, SQLAlchemy 2 + Alembic, pytest, Docker.
## Commands
- Install deps: `uv sync`
- Dev server: `uv run fastapi dev`
- Lint and format: `uv run ruff check . && uv run ruff format .`
- Tests: `uv run pytest`
- New migration: `uv run alembic revision --autogenerate -m "<change>"`
- Apply migrations: `uv run alembic upgrade head`
- Tests: `uv run pytest -q`
- Local services: `docker compose up -d`
## Project structure
- `app/main.py` creates the app; one `APIRouter` per domain in `app/routers/`.
- Pydantic schemas in `app/schemas/`, business logic in `app/services/`.
## How to work in this repo
- Read the relevant files before editing. Follow the patterns already in the codebase over these generic rules.
- Make the smallest change that solves the task. Do not refactor or reformat unrelated code.
- Before saying a task is done, run the type-check, lint and tests listed under Commands and fix what you broke.
- If requirements are ambiguous, ask one clear question instead of guessing.
- Never commit secrets, API keys or `.env` files. Use env vars and keep `.env.example` up to date.
- Do not add a new dependency when the standard library or an existing dependency already covers it.
- Ask before adding, removing or upgrading any dependency.
- Ask before changing database schemas, auth, payments or CI configuration.
- Never delete files, drop data or run destructive commands (`rm -rf`, `git push --force`, `DROP TABLE`) without explicit approval.
- Keep each change under ~200 changed lines where possible; split larger work into steps.
## Python + FastAPI
- Type-hint every function. Use `Annotated[..., Depends(...)]` for dependencies.
- Request and response bodies are Pydantic v2 models; set `response_model` so output is filtered.
- Use `async def` only when the endpoint awaits async I/O. Blocking libraries go in plain `def` endpoints.
- Inject DB sessions, settings and the current user with dependencies, not globals.
- Load settings with `pydantic-settings` from env vars.
- Raise `HTTPException` with a clear `detail` for expected errors.
- Manage dependencies with `uv add <pkg>`; do not hand-edit lock files.
## SQLAlchemy 2 + Alembic
- Use SQLAlchemy 2.0 style: `DeclarativeBase`, `Mapped[...]`, `mapped_column()`, and `select()` statements. No legacy `session.query()`.
- Every schema change gets an Alembic migration; review autogenerated migrations before applying.
- Scope one session per request (via a dependency) and never share sessions across threads.
- Load relationships deliberately with `selectinload` / `joinedload` to avoid N+1 queries.
## pytest
- Tests live in `tests/` named `test_*.py`. Use plain `assert`.
- Share setup with fixtures in `conftest.py`; use `@pytest.mark.parametrize` for input tables.
- Mock external services (HTTP, LLM APIs, payment providers); tests must not hit the network.
- Every bug fix adds a regression test.
## Docker
- Use multi-stage builds and slim, pinned base images.
- Run the app as a non-root user in the final image.
- Keep a `.dockerignore` that excludes `.git`, `node_modules`, `.env` and build output.
- Never bake secrets into images; pass them at runtime.
## Reference docs
- [FastAPI docs](https://fastapi.tiangolo.com)
- [SQLAlchemy docs](https://docs.sqlalchemy.org/en/20/)
- [pytest docs](https://docs.pytest.org)
- [Dockerfile best practices](https://docs.docker.com/build/building/best-practices/)
# Copilot instructions - this project
A Python + FastAPI + SQLAlchemy 2 + Alembic + pytest + Docker project.
Stack: Python + FastAPI, SQLAlchemy 2 + Alembic, pytest, Docker.
## Commands
- Install deps: `uv sync`
- Dev server: `uv run fastapi dev`
- Lint and format: `uv run ruff check . && uv run ruff format .`
- Tests: `uv run pytest`
- New migration: `uv run alembic revision --autogenerate -m "<change>"`
- Apply migrations: `uv run alembic upgrade head`
- Tests: `uv run pytest -q`
- Local services: `docker compose up -d`
## How to work in this repo
- Read the relevant files before editing. Follow the patterns already in the codebase over these generic rules.
- Make the smallest change that solves the task. Do not refactor or reformat unrelated code.
- Before saying a task is done, run the type-check, lint and tests listed under Commands and fix what you broke.
- If requirements are ambiguous, ask one clear question instead of guessing.
- Never commit secrets, API keys or `.env` files. Use env vars and keep `.env.example` up to date.
- Do not add a new dependency when the standard library or an existing dependency already covers it.
- Ask before adding, removing or upgrading any dependency.
- Ask before changing database schemas, auth, payments or CI configuration.
- Never delete files, drop data or run destructive commands (`rm -rf`, `git push --force`, `DROP TABLE`) without explicit approval.
- Keep each change under ~200 changed lines where possible; split larger work into steps.
---
applyTo: "**/*.py"
---
# Python + FastAPI
- Type-hint every function. Use `Annotated[..., Depends(...)]` for dependencies.
- Request and response bodies are Pydantic v2 models; set `response_model` so output is filtered.
- Use `async def` only when the endpoint awaits async I/O. Blocking libraries go in plain `def` endpoints.
- Inject DB sessions, settings and the current user with dependencies, not globals.
- Load settings with `pydantic-settings` from env vars.
- Raise `HTTPException` with a clear `detail` for expected errors.
- Manage dependencies with `uv add <pkg>`; do not hand-edit lock files.
---
applyTo: "**/models/**/*.py,alembic/**"
---
# SQLAlchemy 2 + Alembic
- Use SQLAlchemy 2.0 style: `DeclarativeBase`, `Mapped[...]`, `mapped_column()`, and `select()` statements. No legacy `session.query()`.
- Every schema change gets an Alembic migration; review autogenerated migrations before applying.
- Scope one session per request (via a dependency) and never share sessions across threads.
- Load relationships deliberately with `selectinload` / `joinedload` to avoid N+1 queries.
---
applyTo: "tests/**/*.py,**/test_*.py"
---
# pytest
- Tests live in `tests/` named `test_*.py`. Use plain `assert`.
- Share setup with fixtures in `conftest.py`; use `@pytest.mark.parametrize` for input tables.
- Mock external services (HTTP, LLM APIs, payment providers); tests must not hit the network.
- Every bug fix adds a regression test.
---
applyTo: "Dockerfile,**/Dockerfile,compose.yaml,docker-compose.yml,.dockerignore"
---
# Docker
- Use multi-stage builds and slim, pinned base images.
- Run the app as a non-root user in the final image.
- Keep a `.dockerignore` that excludes `.git`, `node_modules`, `.env` and build output.
- Never bake secrets into images; pass them at runtime.
---
trigger: always_on
---
# this project
A Python + FastAPI + SQLAlchemy 2 + Alembic + pytest + Docker project.
Stack: Python + FastAPI, SQLAlchemy 2 + Alembic, pytest, Docker.
## Commands
- Install deps: `uv sync`
- Dev server: `uv run fastapi dev`
- Lint and format: `uv run ruff check . && uv run ruff format .`
- Tests: `uv run pytest`
- New migration: `uv run alembic revision --autogenerate -m "<change>"`
- Apply migrations: `uv run alembic upgrade head`
- Tests: `uv run pytest -q`
- Local services: `docker compose up -d`
## How to work in this repo
- Read the relevant files before editing. Follow the patterns already in the codebase over these generic rules.
- Make the smallest change that solves the task. Do not refactor or reformat unrelated code.
- Before saying a task is done, run the type-check, lint and tests listed under Commands and fix what you broke.
- If requirements are ambiguous, ask one clear question instead of guessing.
- Never commit secrets, API keys or `.env` files. Use env vars and keep `.env.example` up to date.
- Do not add a new dependency when the standard library or an existing dependency already covers it.
- Ask before adding, removing or upgrading any dependency.
- Ask before changing database schemas, auth, payments or CI configuration.
- Never delete files, drop data or run destructive commands (`rm -rf`, `git push --force`, `DROP TABLE`) without explicit approval.
- Keep each change under ~200 changed lines where possible; split larger work into steps.
---
trigger: glob
globs: **/*.py
---
# Python + FastAPI
- Type-hint every function. Use `Annotated[..., Depends(...)]` for dependencies.
- Request and response bodies are Pydantic v2 models; set `response_model` so output is filtered.
- Use `async def` only when the endpoint awaits async I/O. Blocking libraries go in plain `def` endpoints.
- Inject DB sessions, settings and the current user with dependencies, not globals.
- Load settings with `pydantic-settings` from env vars.
- Raise `HTTPException` with a clear `detail` for expected errors.
- Manage dependencies with `uv add <pkg>`; do not hand-edit lock files.
---
trigger: glob
globs: **/models/**/*.py, alembic/**
---
# SQLAlchemy 2 + Alembic
- Use SQLAlchemy 2.0 style: `DeclarativeBase`, `Mapped[...]`, `mapped_column()`, and `select()` statements. No legacy `session.query()`.
- Every schema change gets an Alembic migration; review autogenerated migrations before applying.
- Scope one session per request (via a dependency) and never share sessions across threads.
- Load relationships deliberately with `selectinload` / `joinedload` to avoid N+1 queries.
---
trigger: glob
globs: tests/**/*.py, **/test_*.py
---
# pytest
- Tests live in `tests/` named `test_*.py`. Use plain `assert`.
- Share setup with fixtures in `conftest.py`; use `@pytest.mark.parametrize` for input tables.
- Mock external services (HTTP, LLM APIs, payment providers); tests must not hit the network.
- Every bug fix adds a regression test.
---
trigger: glob
globs: Dockerfile, **/Dockerfile, compose.yaml, docker-compose.yml, .dockerignore
---
# Docker
- Use multi-stage builds and slim, pinned base images.
- Run the app as a non-root user in the final image.
- Keep a `.dockerignore` that excludes `.git`, `node_modules`, `.env` and build output.
- Never bake secrets into images; pass them at runtime.
# GEMINI.md - this project
Project context for Gemini CLI.
## Project
A Python + FastAPI + SQLAlchemy 2 + Alembic + pytest + Docker project.
Stack: Python + FastAPI, SQLAlchemy 2 + Alembic, pytest, Docker.
## Commands
- Install deps: `uv sync`
- Dev server: `uv run fastapi dev`
- Lint and format: `uv run ruff check . && uv run ruff format .`
- Tests: `uv run pytest`
- New migration: `uv run alembic revision --autogenerate -m "<change>"`
- Apply migrations: `uv run alembic upgrade head`
- Tests: `uv run pytest -q`
- Local services: `docker compose up -d`
## Project structure
- `app/main.py` creates the app; one `APIRouter` per domain in `app/routers/`.
- Pydantic schemas in `app/schemas/`, business logic in `app/services/`.
## How to work in this repo
- Read the relevant files before editing. Follow the patterns already in the codebase over these generic rules.
- Make the smallest change that solves the task. Do not refactor or reformat unrelated code.
- Before saying a task is done, run the type-check, lint and tests listed under Commands and fix what you broke.
- If requirements are ambiguous, ask one clear question instead of guessing.
- Never commit secrets, API keys or `.env` files. Use env vars and keep `.env.example` up to date.
- Do not add a new dependency when the standard library or an existing dependency already covers it.
- Ask before adding, removing or upgrading any dependency.
- Ask before changing database schemas, auth, payments or CI configuration.
- Never delete files, drop data or run destructive commands (`rm -rf`, `git push --force`, `DROP TABLE`) without explicit approval.
- Keep each change under ~200 changed lines where possible; split larger work into steps.
## Python + FastAPI
- Type-hint every function. Use `Annotated[..., Depends(...)]` for dependencies.
- Request and response bodies are Pydantic v2 models; set `response_model` so output is filtered.
- Use `async def` only when the endpoint awaits async I/O. Blocking libraries go in plain `def` endpoints.
- Inject DB sessions, settings and the current user with dependencies, not globals.
- Load settings with `pydantic-settings` from env vars.
- Raise `HTTPException` with a clear `detail` for expected errors.
- Manage dependencies with `uv add <pkg>`; do not hand-edit lock files.
## SQLAlchemy 2 + Alembic
- Use SQLAlchemy 2.0 style: `DeclarativeBase`, `Mapped[...]`, `mapped_column()`, and `select()` statements. No legacy `session.query()`.
- Every schema change gets an Alembic migration; review autogenerated migrations before applying.
- Scope one session per request (via a dependency) and never share sessions across threads.
- Load relationships deliberately with `selectinload` / `joinedload` to avoid N+1 queries.
## pytest
- Tests live in `tests/` named `test_*.py`. Use plain `assert`.
- Share setup with fixtures in `conftest.py`; use `@pytest.mark.parametrize` for input tables.
- Mock external services (HTTP, LLM APIs, payment providers); tests must not hit the network.
- Every bug fix adds a regression test.
## Docker
- Use multi-stage builds and slim, pinned base images.
- Run the app as a non-root user in the final image.
- Keep a `.dockerignore` that excludes `.git`, `node_modules`, `.env` and build output.
- Never bake secrets into images; pass them at runtime.
## Reference docs
- [FastAPI docs](https://fastapi.tiangolo.com)
- [SQLAlchemy docs](https://docs.sqlalchemy.org/en/20/)
- [pytest docs](https://docs.pytest.org)
- [Dockerfile best practices](https://docs.docker.com/build/building/best-practices/)
Commands your agent should run
| Task | Command |
|---|---|
| Install deps | uv sync |
| Dev server | uv run fastapi dev |
| Lint and format | uv run ruff check . && uv run ruff format . |
| Tests | uv run pytest |
| New migration | uv run alembic revision --autogenerate -m "<change>" |
| Apply migrations | uv run alembic upgrade head |
| Tests | uv run pytest -q |
| Local services | docker compose up -d |
What the rules cover
Python + FastAPI
FastAPI service with Pydantic v2 and uv. Scoped to **/*.py in Cursor, Copilot and Windsurf.
- Type-hint every function. Use
Annotated[..., Depends(...)]for dependencies. - Request and response bodies are Pydantic v2 models; set
response_modelso output is filtered. - Use
async defonly when the endpoint awaits async I/O. Blocking libraries go in plaindefendpoints. - Inject DB sessions, settings and the current user with dependencies, not globals.
- Load settings with
pydantic-settingsfrom env vars. - Raise
HTTPExceptionwith a cleardetailfor expected errors. - Manage dependencies with
uv add <pkg>; do not hand-edit lock files.
Source docs: FastAPI docs
SQLAlchemy 2 + Alembic
SQLAlchemy 2.0 ORM with Alembic migrations. Scoped to **/models/**/*.py, alembic/** in Cursor, Copilot and Windsurf.
- Use SQLAlchemy 2.0 style:
DeclarativeBase,Mapped[...],mapped_column(), andselect()statements. No legacysession.query(). - Every schema change gets an Alembic migration; review autogenerated migrations before applying.
- Scope one session per request (via a dependency) and never share sessions across threads.
- Load relationships deliberately with
selectinload/joinedloadto avoid N+1 queries.
Source docs: SQLAlchemy docs
pytest
Python tests with pytest. Scoped to tests/**/*.py, **/test_*.py in Cursor, Copilot and Windsurf.
- Tests live in
tests/namedtest_*.py. Use plainassert. - Share setup with fixtures in
conftest.py; use@pytest.mark.parametrizefor input tables. - Mock external services (HTTP, LLM APIs, payment providers); tests must not hit the network.
- Every bug fix adds a regression test.
Source docs: pytest docs
Docker
Containerised builds and local services with Docker. Scoped to Dockerfile, **/Dockerfile, compose.yaml, docker-compose.yml, .dockerignore in Cursor, Copilot and Windsurf.
- Use multi-stage builds and slim, pinned base images.
- Run the app as a non-root user in the final image.
- Keep a
.dockerignorethat excludes.git,node_modules,.envand build output. - Never bake secrets into images; pass them at runtime.
Source docs: Dockerfile best practices
How to install
- Copy
AGENTS.mdto your repo root. That covers Codex, Cursor, GitHub Copilot and most other agents. - Using Claude Code? Add a
CLAUDE.mdwith the single line@AGENTS.md, or use the standalone CLAUDE.md tab above. - Want rules that only load for certain files in Cursor? Add the
.cursor/rules/*.mdcfiles. - Commit the files so your whole team (and every agent) shares them.
FAQ
Where do I put the AGENTS.md for Python + FastAPI + SQLAlchemy 2 + Alembic + pytest + Docker?
Save it as AGENTS.md in the root of your repository, next to your main config file. Codex, Cursor and GitHub Copilot pick it up automatically. For Claude Code, add a CLAUDE.md containing @AGENTS.md (or use the standalone CLAUDE.md on this page).
What is the most common mistake AI agents make with Python + FastAPI?
Agents mix legacy session.query() with 2.0 style and block the event loop with sync calls in async def.
Which commands should the agent run to check its work?
For this stack: uv sync, uv run fastapi dev, uv run ruff check . && uv run ruff format ., uv run pytest. They are listed in the generated files so the agent runs them before finishing a task.
Do these Python + FastAPI + SQLAlchemy 2 + Alembic + pytest + Docker rules work with Cursor and Claude Code?
Yes. This page includes the same rules as AGENTS.md, CLAUDE.md, Cursor .mdc project rules, a legacy .cursorrules file, GitHub Copilot instructions, Windsurf rules and GEMINI.md.
Can I customise these rules?
Yes. Open this stack in the generator to add or remove libraries, set your project name and package manager, switch beginner explanations on, and download everything as a zip.
Related stacks
Python + FastAPI + LLM / agent SDKs (Python) + pytest
An AI agent backend: FastAPI serving LLM calls and tools.
Python + FastAPI + Supabase + pytest
A FastAPI service on Supabase Postgres and auth.
Python + Django + pytest + Docker
A Django app tested with pytest.
Node.js + Express + Prisma + Zod validation + Vitest + Docker
A TypeScript REST API with Express 5, Prisma and Zod.
Node.js + Express + Drizzle ORM + Zod validation + Docker
An Express API on Drizzle ORM, packaged with Docker.
Python (scripts, agents, libraries) + LLM / agent SDKs (Python) + pytest
A Python AI agent or LLM script with uv, ruff and pytest.