fastapi/fastapi
Architecture
FastAPI is a thin, opinionated layer above two libraries:
- Starlette — supplies the ASGI application, routing primitives, request/response objects, WebSocket handling, middleware stack, background tasks, and
TestClient. - Pydantic v2 — supplies the validation engine, JSON serialization, and JSON-Schema generation that drives both runtime parsing and OpenAPI output.
FastAPI itself contributes:
- A signature-driven dependency-injection system.
- Automatic OpenAPI 3.1 schema generation from those signatures.
Path,Query,Header,Cookie,Body,Form,File,Depends, andSecuritymarkers that make the signature unambiguous.- Standardized validation-error responses and a small set of security scheme classes.
- A bundled Swagger UI and ReDoc, served from
/docsand/redoc.
Component map
graph TD
User[User code: app = FastAPI; @app.get etc.]
User --> App["FastAPI class<br/>fastapi/applications.py"]
App -->|inherits| Starlette["Starlette<br/>(third-party)"]
App -->|owns| Router["APIRouter<br/>fastapi/routing.py"]
App -->|registers| ExHandlers["Exception handlers<br/>fastapi/exception_handlers.py"]
App -->|builds| OpenAPI["OpenAPI generator<br/>fastapi/openapi/utils.py"]
App -->|serves| DocsUI["Swagger UI / ReDoc HTML<br/>fastapi/openapi/docs.py"]
Router -->|each route owns a| Dependant["Dependant tree<br/>fastapi/dependencies/models.py"]
Router -->|wraps with| ExitStack["AsyncExitStackMiddleware<br/>fastapi/middleware/asyncexitstack.py"]
Dependant -->|built by| Resolver["solve_dependencies / get_dependant<br/>fastapi/dependencies/utils.py"]
Resolver -->|uses| Compat["_compat (Pydantic v2 wrapper)<br/>fastapi/_compat/v2.py"]
Resolver -->|uses| Params["Param / Body / Form / File<br/>fastapi/params.py"]
OpenAPI -->|reads| Models["OpenAPI models<br/>fastapi/openapi/models.py"]
OpenAPI -->|reads| Dependant
OpenAPI -->|reads| Compat
Security["fastapi/security/*"] -->|implements| SecBase["SecurityBase<br/>fastapi/security/base.py"]
Security -->|appears as| DependantRequest lifecycle
For an HTTP request to app:
sequenceDiagram
participant Client
participant ASGI as ASGI server (uvicorn)
participant Stack as Starlette middleware stack<br/>(ServerError → user → Exception → AsyncExitStack)
participant Route as APIRoute.get_route_handler
participant Solve as solve_dependencies
participant Endpoint as User function
participant Serialize as serialize_response
Client->>ASGI: HTTP request
ASGI->>Stack: scope, receive, send
Stack->>Route: dispatched by path match
Route->>Solve: walk Dependant tree
Solve->>Solve: resolve Path/Query/Header/Cookie/Body
Solve->>Solve: call sub-Depends (with caching)
Solve-->>Route: kwargs + values, plus errors
alt validation errors
Route-->>Stack: raise RequestValidationError
Stack-->>Client: 422 JSON
else ok
Route->>Endpoint: await endpoint(**values)
Endpoint-->>Route: return value
Route->>Serialize: validate against response_model
Serialize-->>Client: JSONResponse / StreamingResponse / …
endThe two AsyncExitStacks scoped per-request (fastapi_inner_astack, fastapi_function_astack, plus the outer fastapi_middleware_astack) are how dependencies declared with yield get their cleanup blocks called after the response is sent. See request_response() in fastapi/routing.py and AsyncExitStackMiddleware in fastapi/middleware/asyncexitstack.py.
Why Pydantic and Starlette show through
FastAPI deliberately re-exports many third-party types so user code only imports from fastapi:
fastapi.statusisstarlette.status.fastapi.responses.JSONResponse,HTMLResponse,StreamingResponse, etc. are Starlette responses.fastapi.testclient.TestClientisstarlette.testclient.TestClient.fastapi.staticfiles.StaticFiles,fastapi.templating.Jinja2Templates,fastapi.requests.Request,fastapi.websockets.WebSocketall forward to Starlette.
Look at the one-line shim files (fastapi/staticfiles.py, fastapi/templating.py, fastapi/testclient.py, fastapi/requests.py) to see this pattern.
What _compat is for
fastapi/_compat/__init__.py re-exports a small, stable surface (ModelField, Undefined, get_definitions, get_schema_from_model_field, …). The actual implementations now live in fastapi/_compat/v2.py because Pydantic v1 support was dropped — see the PydanticV1NotSupportedError raised in fastapi/utils.py:create_model_field. The _compat boundary used to switch between Pydantic v1 and v2 implementations; today it isolates the rest of FastAPI from Pydantic v2 internals.
Testing architecture
Tests live in tests/. There are three flavours:
- Unit tests for the framework (
tests/test_*.py). - Tutorial tests (
tests/test_tutorial/) — every example indocs_src/is exercised, so the docs cannot drift from the framework's behaviour. - Benchmarks (
tests/benchmarks/) —pytest-codspeedmicro-benchmarks for CodSpeed.
The pyproject coverage config measures fastapi, tests, and docs_src together; that's why the docs source is a first-class part of the codebase.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.
Previous
FastAPI
Next
Getting started