Files
2026-06-01 21:42:05 +00:00

77 lines
5.3 KiB
Markdown

# FastAPI source notes
Repo: `fastapi/fastapi`
Local checkout: `/home/ubuntu/repos/rodin-sources/fastapi`
## Why this repo was chosen
- Core framework source plus first-party docs/tests. It is the best place to separate actual repeated FastAPI conventions from tutorial folklore.
- Especially useful here because the same patterns appear in docs examples, framework internals, and tests: router composition, dependency injection, semantic exceptions, and dependency-driven test seams.
## Repeated patterns
### 1) App assembly is declarative: app-level and router-level configuration carry shared concerns
- `docs_src/bigger_applications/app_an_py310/main.py:7-18` creates the app with a global dependency, then includes routers with per-router prefix/tags/dependencies/responses.
- `docs_src/bigger_applications/app_an_py310/routers/items.py:5-10` shows the same concern split one level down: the router owns prefix/tags/dependencies/common responses.
- `fastapi/applications.py:330-348` documents that `FastAPI(..., dependencies=[...])` applies those dependencies to every path operation, including sub-routers.
Why chosen:
- This is not a one-off tutorial style; the public constructor explicitly supports the same pattern the docs teach.
Implication for synthesis:
- Favor centralized app/router configuration for auth headers, tags, common responses, and prefixes.
- Do not describe thin handlers as a style preference only; the framework API is built to move cross-cutting concerns out of handlers.
### 2) Dependencies are first-class request wiring, including teardown-aware resources
- `docs_src/bigger_applications/app_an_py310/dependencies.py:6-13` keeps request validation in dedicated dependency callables that raise HTTP errors directly.
- `fastapi/routing.py:95-136` wraps request handling in nested `AsyncExitStack`s specifically so dependency setup/teardown, including `yield` dependencies, participates in request lifecycle.
- `tests/test_dependency_security_overrides.py:24-29` defines a route entirely in terms of `Security(...)` and `Depends(...)` collaborators.
Why chosen:
- This combines public examples with internal lifecycle machinery. Dependencies are not sugar over helper calls; they are a core execution model.
Caveat / counterexample:
- `fastapi/routing.py:124-130` raises a `FastAPIError` if application code swallows an exception in a `yield` dependency and fails to re-raise. So "just hide cleanup in a dependency" is incomplete; dependency cleanup must preserve exception flow.
Implication for synthesis:
- Prefer dependencies for auth, validated request context, DB/session access, and request-scoped resources.
- Mention that `yield` dependencies are appropriate when setup/teardown must be coupled to a request.
### 3) Handlers and dependencies raise semantic HTTP exceptions; framework handlers translate them
- `docs_src/bigger_applications/app_an_py310/routers/items.py:21-25` raises `HTTPException(404, ...)` when an item is missing.
- `docs_src/bigger_applications/app_an_py310/routers/items.py:28-38` adds operation-specific response metadata and raises `HTTPException(403, ...)` for forbidden updates.
- `fastapi/exception_handlers.py:11-26` turns `HTTPException` and `RequestValidationError` into HTTP responses, including a 422 JSON body for validation failures.
- `fastapi/exception_handlers.py:13-17` also shows a subtle rule: statuses that must not include a body return a bare `Response`, not JSON.
Why chosen:
- The docs examples and framework exception handlers line up exactly: route code signals semantics, framework code owns response formatting.
Implication for synthesis:
- Recommend raising semantic exceptions from route/dependency code instead of hand-building error JSON in each handler.
- Note that response-body behavior is status-sensitive and partly framework-owned.
### 4) Preferred test seam: override dependencies, not handler internals
- `tests/test_dependency_security_overrides.py:24-29` keeps the route signature explicit about collaborators.
- `tests/test_dependency_security_overrides.py:44-63` replaces both ordinary dependencies and security dependencies through `app.dependency_overrides`, then resets overrides after each test.
Why chosen:
- This is a repo-level testing pattern, not an incidental example.
Caveat / counterexample:
- The reset step is part of the pattern, not cleanup fluff: `tests/test_dependency_security_overrides.py:52-63` clears `app.dependency_overrides = {}` after each override-based test.
Implication for synthesis:
- When describing testing conventions, emphasize overrideable dependency seams as the intended unit of substitution.
## Strong citation candidates
- Global dependencies apply across sub-routers: `fastapi/applications.py:330-348`
- Dependency lifecycle is request-lifecycle machinery, not style guidance: `fastapi/routing.py:95-136`
- `yield` dependency exception-swallowing failure mode: `fastapi/routing.py:124-130`
- Central exception translation, including no-body statuses: `fastapi/exception_handlers.py:11-17`
## Pattern candidates supported by this repo
- centralize cross-cutting concerns in app/router configuration
- use dependencies as the main request-wiring mechanism
- use `yield` dependencies for request-scoped resources with teardown
- raise semantic `HTTPException`s from handlers/dependencies and let framework handlers shape responses
- test by overriding dependencies and resetting overrides explicitly