Skip to content
Web apps

FastAPI service rules

Rules and an endpoint skill for FastAPI with uv and Pydantic v2: Annotated dependencies, typed responses, async only when awaited, lifespan, tested routes.

Verified install Not agent-tested v1.0.0 MIT updated pythonfastapiuvpytest
Equips
  • 1 1 Rules
  • 1 1 Skills
  • – 0 MCP

FastAPI is one of the stacks agents write most often, and the same mistakes keep turning up in their output: blocking calls inside async routes, ORM objects returned unvalidated, Pydantic v1 syntax, on_event hooks, wildcard CORS with credentials. This loadout pins the current conventions from the FastAPI docs (Annotated dependencies, return-type response models, lifespan, dependency overrides in tests) and gives the agent an endpoint skill with an example router and tests that the verifier runs.

What's in it

  • uv for everything: uv add, uv run fastapi dev, uv run pytest
  • Annotated[..., Depends()] aliases and dependency_overrides in tests
  • async def only when everything inside is awaited
  • Typed response models; 201, 404 and 422 handled properly
  • Example router and tests checked by the verifier

You'll need

  • Tools: uv
Level 1 · automated

Verification

Verified install

Checked at commit c77eea0 · 9 passed, 0 failed, 1 not applicable

CheckResultWhat we found
Listinglisting.yaml matches the schema and declares every file in the folder. Pass
Schema valid; 6 files declared, none missing or extra
  • tested.status: untested (agent tests are separate from Level 1)
Files parseJSON parses; SKILL.md and .mdc front matter is valid YAML with the fields each agent needs; code fences are closed. Pass All 6 files parse; front matter valid
AdaptersCLAUDE.md imports @AGENTS.md, GEMINI.md imports @./AGENTS.md, and both match the generator. Pass
CLAUDE.md and GEMINI.md import AGENTS.md and are up to date
  • CLAUDE.md: matches the generator
  • GEMINI.md: matches the generator
Install pathsEvery file lands where each agent documents it, with no collisions, and the laid-out project is re-discovered correctly. Pass
Correct paths for all 6 agents; layouts re-discovered
  • Claude Code: 5 files, 1 skill in .claude/skills/
  • Codex CLI: 4 files, 1 skill in .agents/skills/
  • Cursor: 4 files, 1 skill in .agents/skills/
  • Gemini CLI: 5 files, 1 skill in .agents/skills/
  • Antigravity CLI: 4 files, 1 skill in .agents/skills/
  • GitHub Copilot: 4 files, 1 skill in .agents/skills/
MCP configmcp.json is structurally valid, converts to each agent's format, declares no literal secrets, and referenced packages exist on npm/PyPI. Not applicable No MCP servers in this loadout
Safety scanThe intake scanner finds no credentials, risky shell, hidden Unicode or prompt-injection wording, and the listing's network flag is honest. Pass
Clean: no credentials, risky shell or hidden text
  • Scanner intake-precheck/1: verdict clean; network yes (listing says yes)
ReferencesLinks and file paths between the loadout's files resolve, including for each agent's installed layout. Pass 1 reference between files resolves for every agent
Size limitsFile count and sizes are within the submission limits; SKILL.md bodies stay under 500 lines. Pass
6 files, 6.3 KB total; largest AGENTS.md 2.2 KB
  • Limits: 30 files, 32 KB per file, 128 KB total, 500 lines per skill or rule
LicenceA recognised SPDX licence, with the licence text available. Pass MIT, by Agent Loadout; text in the repository LICENSE
Starter buildA minimal fixture project with the loadout applied installs and builds or type-checks, and the loadout's own code examples compile. Pass
The add-endpoint skill's example router and tests drop into a FastAPI app and pass: 201 on create, 404 on a missing item, 422 on bad input, with a dependency override; ruff check and format are clean
  • Applied 9 loadout files at every agent's paths
  • ✓ place the example router and tests: bash -c mkdir -p tests && cp .agents/skills/add-endpoint/references/items.py app/routers/items.py && cp .agents/skills/add-endpoint/references/test_items.py tests/test_items.py && echo placed
  • ✓ pytest: uv run --no-project --python 3.12 --with fastapi==0.143.3 --with httpx==0.28.1 --with pytest==9.1.1 python -m pytest -q -p no:cacheprovider tests
  • ✓ ruff check: uvx ruff@0.17.1 check app tests
  • ✓ ruff format --check: uvx ruff@0.17.1 format --check app tests
  • Covers: Annotated dependency alias and dependency_overrides in tests (AGENTS.md rules)
  • Covers: Return-type annotations as response models; 201, 404 and automatic 422
  • Covers: Pydantic v2 API only (ConfigDict, model_dump, Field constraints)
  • Covers: lifespan instead of on_event; ruff with the ASYNC rules clean

What this means: a script checked the files themselves: they parse, they install where each agent looks, any MCP config is sound, the safety scan is clean, references between files resolve, and, where a free and repeatable fixture exists, a small starter project builds with the loadout applied. No AI agent was run. Per-agent results ("tested with agent") are separate and stay untested until an agent actually runs.

Install

Choose your agent. Run the commands from your project root, or download a zip already laid out in the right folders.

Claude Code reads CLAUDE.md (imports AGENTS.md with @AGENTS.md) and skills from .claude/skills/.

Download zip
curl -fsSL --create-dirs -o AGENTS.md https://loadout.jnw-it.com/raw/fastapi-service/1.0.0/AGENTS.md
curl -fsSL --create-dirs -o CLAUDE.md https://loadout.jnw-it.com/raw/fastapi-service/1.0.0/CLAUDE.md
curl -fsSL --create-dirs -o .claude/skills/add-endpoint/SKILL.md https://loadout.jnw-it.com/raw/fastapi-service/1.0.0/skills/add-endpoint/SKILL.md
curl -fsSL --create-dirs -o .claude/skills/add-endpoint/references/items.py https://loadout.jnw-it.com/raw/fastapi-service/1.0.0/skills/add-endpoint/references/items.py
curl -fsSL --create-dirs -o .claude/skills/add-endpoint/references/test_items.py https://loadout.jnw-it.com/raw/fastapi-service/1.0.0/skills/add-endpoint/references/test_items.py
FileGoes to
AGENTS.mdAGENTS.md
CLAUDE.mdCLAUDE.md
skills/add-endpoint/SKILL.md.claude/skills/add-endpoint/SKILL.md
skills/add-endpoint/references/items.py.claude/skills/add-endpoint/references/items.py
skills/add-endpoint/references/test_items.py.claude/skills/add-endpoint/references/test_items.py

Already have an AGENTS.md or CLAUDE.md? The commands above overwrite it — download the file instead and merge the sections you want.

Files

Rules AGENTS.md FastAPI, Pydantic v2 and uv rules with commands. 34 lines
Download Raw
# AGENTS.md: FastAPI service

Python API built with FastAPI and Pydantic v2, managed with uv.

## Commands
- Install and sync: `uv sync`. Add a dependency: `uv add <package>` (never `pip install` into the project).
- Run locally: `uv run fastapi dev app/main.py`. Production entry point: `uv run fastapi run app/main.py`.
- Tests: `uv run pytest -q`. Lint and format: `uv run ruff check . && uv run ruff format --check .`.
- Types: `uv run mypy app` if mypy is configured in pyproject.toml.
- Before saying a change is done: tests, ruff check and ruff format all pass.

## Layout
- `app/main.py` creates the app and includes routers. One `APIRouter` per resource in `app/routers/`.
- Request and response models in `app/schemas/`; database models separate from API models.
- Settings in `app/config.py` with pydantic-settings `BaseSettings`, read from the environment. No values in code.

## Rules
- Dependencies with `Annotated[T, Depends(...)]`; define reusable aliases (`SessionDep`, `CurrentUser`).
- Every route declares its response type (return annotation or `response_model`) so output is validated and documented.
  Never return ORM objects or dicts with extra fields straight from a route.
- Use `async def` only when everything awaited inside is async. Blocking calls (most DB drivers, `requests`, file I/O)
  go in plain `def` routes, which FastAPI runs in a threadpool. Never call blocking code inside `async def`.
- Startup and shutdown in a `lifespan` context manager, not `@app.on_event`.
- Errors: raise `HTTPException` with the right status (404 missing, 409 conflict, 422 is automatic for bad input).
  Do not return 200 with an error body.
- Pydantic v2 only: `model_config = ConfigDict(...)`, `model_dump()`, `field_validator`. No v1 `class Config` or `.dict()`.
- Auth: check it in a dependency, not inside each route. Never log tokens, passwords or full request bodies.
- CORS: list exact origins. Never `allow_origins=["*"]` together with `allow_credentials=True`.

## Tests
- `TestClient(app)` for HTTP tests. Swap dependencies with `app.dependency_overrides[...]`, and clear them after.
- Every new route gets a happy-path test and at least one failure test (404, 422 or auth).
- New endpoints: use the `add-endpoint` skill.
Adapter CLAUDE.md Imports AGENTS.md for Claude Code. 10 lines
Download Raw
# CLAUDE.md

@AGENTS.md

## Claude Code notes
- Skills from this loadout live in `.claude/skills/`: `add-endpoint`. Use them when their description matches the task.
- Follow AGENTS.md above; where this file and AGENTS.md disagree, AGENTS.md wins.

<!-- From the Agent Loadout "FastAPI service rules" v1.0.0 — https://loadout.jnw-it.com/loadouts/fastapi-service/ -->
Adapter GEMINI.md Imports AGENTS.md for Gemini CLI. 10 lines
Download Raw
# GEMINI.md

@./AGENTS.md

## Gemini CLI notes
- Skills from this loadout live in `.agents/skills/`: `add-endpoint`. Use them when their description matches the task.
- Follow AGENTS.md above; where this file and AGENTS.md disagree, AGENTS.md wins.

<!-- From the Agent Loadout "FastAPI service rules" v1.0.0 — https://loadout.jnw-it.com/loadouts/fastapi-service/ -->
Skill skills/add-endpoint/SKILL.md Add a typed, tested FastAPI route. 17 lines
Download Raw
---
name: add-endpoint
description: Add a FastAPI endpoint with typed request and response models, an Annotated dependency and tests for success and failure. Use when adding or changing a route.
---

# Add an endpoint

1. Read `app/main.py` and the router for the resource. If there is no router yet, start from `references/items.py`.
2. Define models: a `Create` model for input and a `Public` model for output. Output models never include secrets or
   internal fields.
3. Write the route with a return annotation, the right status code (`status_code=201` for creation) and dependencies via
   `Annotated[..., Depends(...)]`. Plain `def` if it calls blocking code.
4. Raise `HTTPException(status_code=404, ...)` for missing items. Let FastAPI return 422 for invalid input.
5. Include the router in `app/main.py` if new: `app.include_router(items.router)`.
6. Tests, following `references/test_items.py`: success, 404, 422, and a dependency override instead of real storage.
7. Run `uv run pytest -q`, `uv run ruff check .` and `uv run ruff format --check .`. Report the results.
Skill file skills/add-endpoint/references/items.py Example router with models and a dependency. 57 lines
Download Raw
"""Example router: typed models, an Annotated dependency, correct status codes."""

from typing import Annotated

from fastapi import APIRouter, Depends, HTTPException, status
from pydantic import BaseModel, ConfigDict, Field


class ItemCreate(BaseModel):
    name: str = Field(min_length=1, max_length=100)
    price_pence: int = Field(ge=0)


class ItemPublic(BaseModel):
    model_config = ConfigDict(from_attributes=True)

    id: int
    name: str
    price_pence: int


class ItemStore:
    """In-memory store. Replace with the project's database session dependency."""

    def __init__(self) -> None:
        self.items: dict[int, ItemPublic] = {}

    def add(self, data: ItemCreate) -> ItemPublic:
        item = ItemPublic(id=len(self.items) + 1, **data.model_dump())
        self.items[item.id] = item
        return item


_store = ItemStore()


def get_store() -> ItemStore:
    return _store


StoreDep = Annotated[ItemStore, Depends(get_store)]

router = APIRouter(prefix="/items", tags=["items"])


@router.post("", status_code=status.HTTP_201_CREATED)
def create_item(data: ItemCreate, store: StoreDep) -> ItemPublic:
    return store.add(data)


@router.get("/{item_id}")
def read_item(item_id: int, store: StoreDep) -> ItemPublic:
    item = store.items.get(item_id)
    if item is None:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Item not found")
    return item
Skill file skills/add-endpoint/references/test_items.py Tests for success, 404 and 422 with an override. 33 lines
Download Raw
"""Tests for the items router: success, 404, 422, with the store swapped by a dependency override."""

import pytest
from fastapi.testclient import TestClient

from app.main import app
from app.routers.items import ItemStore, get_store


@pytest.fixture
def client():
    store = ItemStore()
    app.dependency_overrides[get_store] = lambda: store
    with TestClient(app) as c:
        yield c
    app.dependency_overrides.clear()


def test_create_and_read(client):
    r = client.post("/items", json={"name": "Tea", "price_pence": 250})
    assert r.status_code == 201
    item = r.json()
    assert item == {"id": 1, "name": "Tea", "price_pence": 250}
    assert client.get(f"/items/{item['id']}").json() == item


def test_missing_item_is_404(client):
    assert client.get("/items/999").status_code == 404


def test_invalid_input_is_422(client):
    assert client.post("/items", json={"name": "", "price_pence": -1}).status_code == 422

All files: source zip · Licence MIT · By Agent Loadout · First listed

Installing and testing

How do I install FastAPI service rules in Claude Code?

From your project root, put AGENTS.md, CLAUDE.md, skills/add-endpoint/SKILL.md at .claude/skills/add-endpoint/SKILL.md, skills/add-endpoint/references/items.py at .claude/skills/add-endpoint/references/items.py, skills/add-endpoint/references/test_items.py at .claude/skills/add-endpoint/references/test_items.py. The "Claude Code" tab on this page has the curl commands, or download https://loadout.jnw-it.com/download/fastapi-service/claude-code.zip, which is already laid out. Do not overwrite an existing AGENTS.md or CLAUDE.md; merge it.

How do I install FastAPI service rules in Codex CLI?

From your project root, put AGENTS.md, skills/add-endpoint/SKILL.md at .agents/skills/add-endpoint/SKILL.md, skills/add-endpoint/references/items.py at .agents/skills/add-endpoint/references/items.py, skills/add-endpoint/references/test_items.py at .agents/skills/add-endpoint/references/test_items.py. The "Codex CLI" tab on this page has the curl commands, or download https://loadout.jnw-it.com/download/fastapi-service/codex.zip, which is already laid out. Do not overwrite an existing AGENTS.md or CLAUDE.md; merge it.

How do I install FastAPI service rules in Cursor?

From your project root, put AGENTS.md, skills/add-endpoint/SKILL.md at .agents/skills/add-endpoint/SKILL.md, skills/add-endpoint/references/items.py at .agents/skills/add-endpoint/references/items.py, skills/add-endpoint/references/test_items.py at .agents/skills/add-endpoint/references/test_items.py. The "Cursor" tab on this page has the curl commands, or download https://loadout.jnw-it.com/download/fastapi-service/cursor.zip, which is already laid out. Do not overwrite an existing AGENTS.md or CLAUDE.md; merge it.

How do I install FastAPI service rules in Gemini CLI?

From your project root, put AGENTS.md, GEMINI.md, skills/add-endpoint/SKILL.md at .agents/skills/add-endpoint/SKILL.md, skills/add-endpoint/references/items.py at .agents/skills/add-endpoint/references/items.py, skills/add-endpoint/references/test_items.py at .agents/skills/add-endpoint/references/test_items.py. The "Gemini CLI" tab on this page has the curl commands, or download https://loadout.jnw-it.com/download/fastapi-service/gemini-cli.zip, which is already laid out. Do not overwrite an existing AGENTS.md or CLAUDE.md; merge it.

How do I install FastAPI service rules in Antigravity CLI?

From your project root, put AGENTS.md, skills/add-endpoint/SKILL.md at .agents/skills/add-endpoint/SKILL.md, skills/add-endpoint/references/items.py at .agents/skills/add-endpoint/references/items.py, skills/add-endpoint/references/test_items.py at .agents/skills/add-endpoint/references/test_items.py. The "Antigravity CLI" tab on this page has the curl commands, or download https://loadout.jnw-it.com/download/fastapi-service/antigravity-cli.zip, which is already laid out. Do not overwrite an existing AGENTS.md or CLAUDE.md; merge it.

How do I install FastAPI service rules in GitHub Copilot?

From your project root, put AGENTS.md, skills/add-endpoint/SKILL.md at .agents/skills/add-endpoint/SKILL.md, skills/add-endpoint/references/items.py at .agents/skills/add-endpoint/references/items.py, skills/add-endpoint/references/test_items.py at .agents/skills/add-endpoint/references/test_items.py. The "GitHub Copilot" tab on this page has the curl commands, or download https://loadout.jnw-it.com/download/fastapi-service/copilot.zip, which is already laid out. Do not overwrite an existing AGENTS.md or CLAUDE.md; merge it.

Has FastAPI service rules been tested?

It passed the Level 1 automated install checks on 2026-10-17: the files parse, install to each agent's documented paths, and pass the safety scan. No AI agent has run it yet, so no agent pass or fail is claimed.

More for Claude Code, Codex, Cursor, Gemini CLI, Antigravity CLI and GitHub Copilot.