# Contributor handoff — fastapi/fastapi

> Canonical page: https://codevetter.com/unpack/fastapi/agent-handoff

# Contributor handoff — fastapi/fastapi

Scanned commit 50113da16fec53b66b80d75e80a89296de4fa5a5 (2026-09-01). Generated by codevetter codevetter 1.12.0 on 2026-09-22.

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). — [fastapi/.agents/skills/fastapi/SKILL.md](https://github.com/fastapi/fastapi/blob/50113da16fec53b66b80d75e80a89296de4fa5a5/fastapi/.agents/skills/fastapi/SKILL.md) [fastapi/applications.py](https://github.com/fastapi/fastapi/blob/50113da16fec53b66b80d75e80a89296de4fa5a5/fastapi/applications.py) [fastapi/routing.py](https://github.com/fastapi/fastapi/blob/50113da16fec53b66b80d75e80a89296de4fa5a5/fastapi/routing.py) [fastapi/dependencies/utils.py](https://github.com/fastapi/fastapi/blob/50113da16fec53b66b80d75e80a89296de4fa5a5/fastapi/dependencies/utils.py) [fastapi/_compat/v2.py](https://github.com/fastapi/fastapi/blob/50113da16fec53b66b80d75e80a89296de4fa5a5/fastapi/_compat/v2.py)
- 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`. — [scripts/test.sh](https://github.com/fastapi/fastapi/blob/50113da16fec53b66b80d75e80a89296de4fa5a5/scripts/test.sh) [scripts/lint.sh](https://github.com/fastapi/fastapi/blob/50113da16fec53b66b80d75e80a89296de4fa5a5/scripts/lint.sh) [scripts/format.sh](https://github.com/fastapi/fastapi/blob/50113da16fec53b66b80d75e80a89296de4fa5a5/scripts/format.sh)
- 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`). — [.github/workflows/test.yml#L300-340](https://github.com/fastapi/fastapi/blob/50113da16fec53b66b80d75e80a89296de4fa5a5/.github/workflows/test.yml#L300-L340) [pyproject.toml#L198-220](https://github.com/fastapi/fastapi/blob/50113da16fec53b66b80d75e80a89296de4fa5a5/pyproject.toml#L198-L220) [fastapi/dependencies/models.py#L140-146](https://github.com/fastapi/fastapi/blob/50113da16fec53b66b80d75e80a89296de4fa5a5/fastapi/dependencies/models.py#L140-L146)
- 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. — [scripts/test.sh#L5-6](https://github.com/fastapi/fastapi/blob/50113da16fec53b66b80d75e80a89296de4fa5a5/scripts/test.sh#L5-L6) [pyproject.toml#L189](https://github.com/fastapi/fastapi/blob/50113da16fec53b66b80d75e80a89296de4fa5a5/pyproject.toml#L189) [tests/test_tutorial/test_security/test_tutorial001.py](https://github.com/fastapi/fastapi/blob/50113da16fec53b66b80d75e80a89296de4fa5a5/tests/test_tutorial/test_security/test_tutorial001.py)
- 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. — [.github/workflows/test.yml#L14-17](https://github.com/fastapi/fastapi/blob/50113da16fec53b66b80d75e80a89296de4fa5a5/.github/workflows/test.yml#L14-L17) [pyproject.toml#L263-266](https://github.com/fastapi/fastapi/blob/50113da16fec53b66b80d75e80a89296de4fa5a5/pyproject.toml#L263-L266)
- 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]`. — [.github/workflows/guard-dependencies.yml#L15-50](https://github.com/fastapi/fastapi/blob/50113da16fec53b66b80d75e80a89296de4fa5a5/.github/workflows/guard-dependencies.yml#L15-L50)
- 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. — [.pre-commit-config.yaml#L60-90](https://github.com/fastapi/fastapi/blob/50113da16fec53b66b80d75e80a89296de4fa5a5/.pre-commit-config.yaml#L60-L90) [scripts/docs.py#L40-55](https://github.com/fastapi/fastapi/blob/50113da16fec53b66b80d75e80a89296de4fa5a5/scripts/docs.py#L40-L55)
- 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. — [fastapi/routing.py#L3305-3311](https://github.com/fastapi/fastapi/blob/50113da16fec53b66b80d75e80a89296de4fa5a5/fastapi/routing.py#L3305-L3311) [fastapi/routing.py#L1828-1852](https://github.com/fastapi/fastapi/blob/50113da16fec53b66b80d75e80a89296de4fa5a5/fastapi/routing.py#L1828-L1852) [fastapi/openapi/utils.py#L551-582](https://github.com/fastapi/fastapi/blob/50113da16fec53b66b80d75e80a89296de4fa5a5/fastapi/openapi/utils.py#L551-L582)
- 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. — [fastapi/routing.py#L2570-2585](https://github.com/fastapi/fastapi/blob/50113da16fec53b66b80d75e80a89296de4fa5a5/fastapi/routing.py#L2570-L2585) [fastapi/applications.py#L1084-1103](https://github.com/fastapi/fastapi/blob/50113da16fec53b66b80d75e80a89296de4fa5a5/fastapi/applications.py#L1084-L1103)
- 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. — [fastapi/middleware/asyncexitstack.py#L10-18](https://github.com/fastapi/fastapi/blob/50113da16fec53b66b80d75e80a89296de4fa5a5/fastapi/middleware/asyncexitstack.py#L10-L18) [fastapi/routing.py#L134-155](https://github.com/fastapi/fastapi/blob/50113da16fec53b66b80d75e80a89296de4fa5a5/fastapi/routing.py#L134-L155) [fastapi/dependencies/utils.py#L601-609](https://github.com/fastapi/fastapi/blob/50113da16fec53b66b80d75e80a89296de4fa5a5/fastapi/dependencies/utils.py#L601-L609) [fastapi/dependencies/utils.py#L666-676](https://github.com/fastapi/fastapi/blob/50113da16fec53b66b80d75e80a89296de4fa5a5/fastapi/dependencies/utils.py#L666-L676)
- 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. — [fastapi/routing.py#L605-614](https://github.com/fastapi/fastapi/blob/50113da16fec53b66b80d75e80a89296de4fa5a5/fastapi/routing.py#L605-L614) [fastapi/routing.py#L650-656](https://github.com/fastapi/fastapi/blob/50113da16fec53b66b80d75e80a89296de4fa5a5/fastapi/routing.py#L650-L656) [fastapi/routing.py#L690-698](https://github.com/fastapi/fastapi/blob/50113da16fec53b66b80d75e80a89296de4fa5a5/fastapi/routing.py#L690-L698)
- 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. — [fastapi/staticfiles.py](https://github.com/fastapi/fastapi/blob/50113da16fec53b66b80d75e80a89296de4fa5a5/fastapi/staticfiles.py) [fastapi/requests.py](https://github.com/fastapi/fastapi/blob/50113da16fec53b66b80d75e80a89296de4fa5a5/fastapi/requests.py) [fastapi/middleware/__init__.py](https://github.com/fastapi/fastapi/blob/50113da16fec53b66b80d75e80a89296de4fa5a5/fastapi/middleware/__init__.py) [fastapi/logger.py](https://github.com/fastapi/fastapi/blob/50113da16fec53b66b80d75e80a89296de4fa5a5/fastapi/logger.py)
- 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). — [fastapi/param_functions.py](https://github.com/fastapi/fastapi/blob/50113da16fec53b66b80d75e80a89296de4fa5a5/fastapi/param_functions.py) [fastapi/__init__.py#L5-25](https://github.com/fastapi/fastapi/blob/50113da16fec53b66b80d75e80a89296de4fa5a5/fastapi/__init__.py#L5-L25) [pyproject.toml#L241-260](https://github.com/fastapi/fastapi/blob/50113da16fec53b66b80d75e80a89296de4fa5a5/pyproject.toml#L241-L260)
- 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. — [scripts/test.sh#L6](https://github.com/fastapi/fastapi/blob/50113da16fec53b66b80d75e80a89296de4fa5a5/scripts/test.sh#L6) [tests/test_dump_json_fast_path.py#L14-27](https://github.com/fastapi/fastapi/blob/50113da16fec53b66b80d75e80a89296de4fa5a5/tests/test_dump_json_fast_path.py#L14-L27) [tests/test_security_http_basic_realm.py#L8-19](https://github.com/fastapi/fastapi/blob/50113da16fec53b66b80d75e80a89296de4fa5a5/tests/test_security_http_basic_realm.py#L8-L19)

Every claim links to its cited files at the pinned commit. Citations identify source evidence; they do not establish runtime correctness. Independent CodeVetter scan — not reviewed by upstream maintainers.

## Public product links

- [CodeVetter](https://codevetter.com/)
- [Download](https://codevetter.com/download)
- [Documentation](https://codevetter.com/docs/)
- [Source](https://github.com/Codevetter/codevetter)
