fastapi/fastapi
Read `fastapi/.agents/skills/fastapi/SKILL.md` first — it is the project's own statement of intended API style and is authoritative for any user-facing example you write. Then read `fastapi/routing.py` (specifically `get_request_handler`, `include_router`, and the `_IncludedRouter`/`_EffectiveRouteContext` pair) and `fastapi/dependencies/utils.py` (`get_dependant`, `analyze_param`, `solve_dependencies`), because nearly every behavioural change lands in one of those. The hard constraints are 100% coverage, strict mypy plus ty, `filterwarnings = ["error"]`, and `inline-snapshot` review mode — a change that is functionally right but leaves a line uncovered or emits a warning will fail CI. Dependency files are off-limits to non-org contributors and enforced by a workflow that auto-closes such PRs.
- Read first, in order: `fastapi/.agents/skills/fastapi/SKILL.md` (conventions), `fastapi/applications.py#L873-1164` (app construction), `fastapi/routing.py#L375-762` (the request handler), `fastapi/dependencies/utils.py#L271-733` (dependency graph + solving), `fastapi/_compat/v2.py#L114-235` (ModelField).
- Run `bash scripts/test.sh` for the suite and `bash scripts/lint.sh` before proposing a change; `scripts/format.sh` applies `ruff --fix` and `ruff format` across `fastapi tests docs_src scripts`.
- Any new library code must be covered — CI runs `coverage report --fail-under=100` over `fastapi`, `tests` and `docs_src` combined, so genuinely unreachable branches need an explicit `# pragma: no cover` (the existing convention in `fastapi/dependencies/models.py`).
- New documentation examples belong in `docs_src/<topic>/tutorialNNN_py310.py` with a matching `tests/test_tutorial/test_<topic>/test_tutorialNNN.py`; `docs_src` is on `PYTHONPATH` during tests and excluded from pytest collection.
- Snapshot assertions must not be silently regenerated: CI sets `INLINE_SNAPSHOT_DEFAULT_FLAGS: review`, and the `[tool.inline-snapshot]` fix/create flags in `pyproject.toml` are commented out on purpose.
- Do not edit `pyproject.toml` or `uv.lock` on behalf of an outside contributor: `guard-dependencies.yml` auto-comments and closes any PR touching them unless the author is an org MEMBER/OWNER or `dependabot[bot]`.
- Only `docs/en/` is hand-edited; the `ensure-non-translated` pre-commit hook rejects modifications to non-English docs outside the translated set, and `README.md` is generated from `docs/en/docs/index.md` by the `generate-readme` hook.
- Trap: `include_router` no longer copies routes. Code that assumes `app.routes` is a flat list of `APIRoute` objects will silently miss included routes — iterate with `routing.iter_route_contexts(routes)` and unwrap via `RouteContext`, the way `get_fields_from_routes` does.
- Trap: after adding or mutating routes at runtime you must go through `add_route`/`add_api_route`/`include_router`/`frontend`, all of which call `_mark_routes_changed()`; appending directly to `router.routes` will leave the cached `app.openapi_schema` stale.
- Trap: three distinct `AsyncExitStack`s live in the scope with different lifetimes — `fastapi_middleware_astack` (files), `fastapi_inner_astack` (request-scoped yield deps and the SSE producer), `fastapi_function_astack` (function-scoped yield deps). Picking the wrong one changes when teardown runs relative to the response being sent.
- Trap: every new streaming code path needs an `await anyio.sleep(0)` checkpoint after each yielded chunk, or client-disconnect cancellation is never delivered — the existing sites cite issue #14680.
- Safe edit boundary: `fastapi/staticfiles.py`, `fastapi/templating.py`, `fastapi/testclient.py`, `fastapi/requests.py`, `fastapi/websockets.py`, `fastapi/logger.py` and `fastapi/middleware/*.py` (except `asyncexitstack.py`) are pure re-exports — behaviour changes belong upstream in Starlette, not here.
- Style conventions to match: parameters documented with `Annotated[..., Doc("""...""")]` from `annotated_doc`, `from __future__` never used (ruff keeps runtime typing), PEP 604 unions throughout, and `from x import Y as Y` re-export form in `__init__.py` files (which are exempt from F401).
- The suite runs under pytest-xdist with `--dist loadgroup`; module-level `app = FastAPI()` plus `client = TestClient(app)` is the established per-file pattern, so avoid cross-file shared mutable state.