BoilerplateHub

Python / FastAPI AGENTS.md Template

For an HTTP API built with FastAPI, SQLAlchemy 2.0 async sessions, Alembic migrations, and Pydantic v2 schemas. It assumes uv for dependency management and ruff for linting and formatting. Use it for a standalone service rather than a Django style full stack app.

FastAPIPythonSQLAlchemyAlembicpytest
AGENTS.md
Download
# AGENTS.md

This is an async HTTP API built with FastAPI, SQLAlchemy 2.0, and PostgreSQL.

## Project

Stack: Python 3.12, FastAPI, SQLAlchemy 2.0 (async), Alembic, Pydantic v2, PostgreSQL, uv, ruff, pytest.

Layout:

- `app/main.py` application factory, middleware, router registration
- `app/api/v1/` routers, one module per resource
- `app/schemas/` Pydantic request and response models
- `app/models/` SQLAlchemy ORM models
- `app/services/` business logic, the only layer that composes repositories
- `app/repositories/` database access, one per aggregate
- `app/core/config.py` Settings loaded from the environment
- `app/core/deps.py` dependency providers (session, current user)
- `alembic/versions/` generated migrations
- `tests/` mirrors the `app/` tree

Entry points: `app/main.py`, `app/core/config.py`, `app/core/deps.py`.

## Commands

Use uv. Do not use pip, poetry, or a bare virtualenv.

```bash
uv sync                                  # install dependencies from uv.lock
uv run uvicorn app.main:app --reload     # dev server on :8000
uv run ruff check .                      # lint
uv run ruff format .                     # format
uv run mypy app                          # type check
uv run pytest                            # full test suite
uv run pytest tests/api/test_users.py -k create   # one test
uv run alembic revision --autogenerate -m "add user table"
uv run alembic upgrade head              # apply migrations
uv run alembic downgrade -1              # roll back one revision
```

Add a dependency with `uv add <package>`, never by editing pyproject.toml by hand.

Before returning work run `uv run ruff check .`, `uv run mypy app`, and `uv run pytest`.

## Code style

- Every route handler is `async def`. Never call a blocking library inside one, wrap it in `anyio.to_thread.run_sync`.
- Never use the sync SQLAlchemy session. Sessions come from `app.core.deps.get_session` via `Depends`.
- Routers contain no business logic. They validate input, call a service, and shape the response.
- Pydantic schemas are the only types crossing the HTTP boundary. ORM models never leave the service layer.
- Full type hints on every function, including return types. `Any` requires a comment explaining why.
- Raise `HTTPException` with an explicit status code, never return a bare error dict.
- Configuration is read from `Settings` only. No `os.environ` access outside `app/core/config.py`.
- Line length 100, enforced by ruff. Double quotes.
- No wildcard imports, no mutable default arguments.

## Boundaries

Do not touch without explicit instruction:

- Existing files in `alembic/versions/`. Migrations are generated and append only. Never edit or delete a revision that has been applied.
- `uv.lock`. Use `uv add` and `uv sync`.
- `.env` and anything holding a credential. Document new settings in `.env.example`.
- `Dockerfile`, `docker-compose.yml`, `.github/workflows/`.

Needs human review: authentication and permission dependencies in `app/core/deps.py`, rate limiting, any migration that drops or renames a column, and changes to a public response schema.

If a model change implies a migration, generate it, print the SQL, and stop for review before applying it anywhere but the local database.

## Testing

- `uv run pytest` runs everything against a disposable test database created per session.
- Every endpoint has at least a success test and a failure test covering validation and authorization.
- Service layer functions with branching logic require unit tests.
- Repositories are exercised through service tests, not mocked.
- Use the factories in `tests/factories.py` rather than constructing models inline.
- A bug fix includes a regression test that fails without the fix.

## Git workflow

- Branch from `main`: `feat/short-description`, `fix/short-description`.
- Conventional commits: `feat(users): add email verification endpoint`.
- A migration and the code that depends on it ship in the same commit.
- Never commit to `main` directly, never force push a shared branch.
- PR description lists new environment variables, migrations to run, and any breaking API change.

What each section does

Project

FastAPI projects vary wildly in layout, so an agent cannot infer where routers, schemas, and models belong. Naming the layers and the dependency injection entry points stops it from putting database code inside a route function. It also clarifies the split between Pydantic schemas and ORM models, which is the most common source of confusion.

Commands

Python tooling is fragmented enough that guessing between pip, poetry, and uv wastes a whole turn and can corrupt the environment. Pinning the exact commands, including how to run a single test and how to create a migration, makes the agent self-sufficient. Alembic commands especially need to be exact because a wrong revision is painful to undo.

Code style

Async correctness is the rule that breaks a FastAPI service in production and does not show up in a linter. Type hints, Pydantic boundaries, and explicit error handling are the checkable rules worth writing down. Formatting is delegated to ruff and needs no prose.

Boundaries

Alembic migration files are generated and ordered, so hand edits create revisions that cannot be replayed. Secrets, lockfiles, and deployment config carry the same risk here as anywhere. Marking auth and permissions as human review keeps security decisions with a person.

Testing

An API is mostly integration surface, so the useful rule is which endpoints must have a test rather than a coverage number. Documenting the test database setup prevents the agent from running tests against development data. Fixtures and factories should be reused rather than reinvented per test.

Git workflow

Migrations and code must land together or a deploy breaks, so the workflow section should say so explicitly. Commit conventions keep the changelog readable when several services share a release process. State the PR expectations around migrations clearly.

Which agents read this file?

Claude Code looks for CLAUDE.md. Most other agents and editors read AGENTS.md. Rather than maintaining both and letting them drift, keep one real file and symlink the other:

ln -s AGENTS.md CLAUDE.md
git add AGENTS.md CLAUDE.md

Git stores the symlink, so it survives cloning on macOS and Linux. On Windows it needs developer mode or a stub file that references the real one. The full comparison is in CLAUDE.md vs AGENTS.md.

Other templates

Reviews

Leave a comment

Your rating (optional)

0/2000