Skip to main content

Architecture Overview

This section contains architecture diagrams and documentation for etchblok-test-api.

Available Diagrams

FastAPI Ecosystem Context

The FastAPI Ecosystem Context diagram illustrates how the FastAPI framework sits at the center of a modern web development stack.

Key Components:

  • FastAPI Framework: The core library that developers use to define routes, dependencies, and data models. It leverages FastAPI Ecosystem Context for its underlying web capabilities (routing, middleware, etc.) and Data Modeling with JSON Schema for robust data validation and serialization.
  • Developer: The primary user who writes the API code, uses the FastAPI CLI for development, and interacts with the generated documentation.
  • End User: The consumer of the API, sending HTTP requests that are handled by the server.
  • ASGI Server: High-performance servers like Uvicorn or Gunicorn that host the FastAPI application and manage the asynchronous request/response lifecycle.
  • Interactive Docs: FastAPI automatically generates and serves Swagger UI and ReDoc, which provide a web interface for exploring and testing the API.
  • External Systems: FastAPI applications typically interact with Databases (often via SQLAlchemy or SQLModel) and other External APIs (using clients like httpx).

The diagram highlights the "batteries-included" nature of FastAPI, where it orchestrates multiple specialized libraries to provide a cohesive developer experience.

Key Architectural Findings:

  • FastAPI is a wrapper around Starlette (web core) and Pydantic (data validation), inheriting Starlette's application class.
  • The framework automatically generates OpenAPI schemas and provides built-in support for Swagger UI and ReDoc via CDNs.
  • FastAPI relies on ASGI servers (Uvicorn, Gunicorn) to handle concurrent asynchronous connections.
  • It is designed to be database-agnostic but has deep integration patterns for SQLAlchemy and SQLModel.
  • A separate CLI tool (fastapi-cli) is provided for common development tasks like running the server with hot-reload.

FastAPI Internal Component Architecture

The component architecture of FastAPI is centered around the FastAPI class, which extends Starlette to provide a high-level API for building web services.

Key components include:

  • Core Application: The FastAPI class orchestrates the application, using APIRouter and APIRoute to manage path operations.
  • Dependency Injection (DI) System: This is the heart of FastAPI. It uses a Dependant model to represent the tree of dependencies for each endpoint. The solve_dependencies function is responsible for resolving these at request time, extracting values from the request (Query, Path, Body, etc.).
  • Parameter Metadata: Modules like fastapi.params and fastapi.param_functions define the metadata used by the DI system to know how to extract and validate data.
  • OpenAPI Generation: FastAPI automatically generates an OpenAPI schema by inspecting the routes and their dependency trees. This schema is then used to serve interactive documentation via Swagger UI or ReDoc.
  • Security: A dedicated security subsystem provides reusable dependencies for various authentication schemes (OAuth2, API Key, HTTP Basic/Bearer), which integrate seamlessly with the DI system and OpenAPI generation.

Key Architectural Findings:

  • FastAPI inherits from Starlette but significantly extends it with a custom routing and dependency injection system.
  • The 'Dependant' class in 'fastapi.dependencies.models' is the core data structure representing an endpoint's requirements.
  • 'solve_dependencies' in 'fastapi.dependencies.utils' is the runtime engine that executes the dependency graph for every request.
  • OpenAPI generation is deeply integrated, inspecting the same 'Dependant' structures used for request processing.
  • Parameter functions like 'Query', 'Path', and 'Body' are factory functions that create metadata objects used for both validation and documentation.

FastAPI HTTP Request-Response Lifecycle

This sequence diagram traces the lifecycle of an asynchronous HTTP request in FastAPI, from the initial ASGI entry point to the final response serialization and delivery.

The process begins when an FastAPI Ecosystem Context (like Uvicorn) calls the FastAPI application's __call__ method. The request then traverses a stack of Background Tasks and Middleware, including ServerErrorMiddleware, ExceptionMiddleware, and AsyncExitStackMiddleware, before reaching the APIRoute.

Inside the APIRoute, a request handler is generated. This handler first invokes the Dependency Resolution and Solved Results (solve_dependencies), which extracts data from the Request object (such as path parameters, query parameters, and the request body) and recursively resolves any defined dependencies.

Once dependencies are resolved, the actual Defining Path Operations (the user-defined endpoint) is executed via run_endpoint_function. The result of this function is then passed to the fastapi.encoders (serialize_response), which utilizes jsonable_encoder to convert complex objects (like Pydantic models or dataclasses) into JSON-compatible formats.

Finally, a Response object (typically a JSONResponse) is created and executed as an ASGI application, sending the serialized data and headers back through the middleware stack to the ASGI server and ultimately to the client.

Key architectural components discovered:

  • FastAPI App: The main entry point inheriting from Starlette.
  • APIRoute: Manages the mapping between URL paths and endpoint functions, handling the ASGI request/response flow for a specific route.
  • Dependency Resolver: A core FastAPI feature that automates parameter extraction and dependency injection.
  • jsonable_encoder: A utility that ensures all returned data is JSON-compatible, supporting Pydantic models, dataclasses, and standard Python types.
  • AsyncExitStack: Used extensively to manage the lifecycle of dependencies (especially those using yield) and ensure resources are properly closed.

Key Architectural Findings:

  • FastAPI inherits from Starlette and extends its routing and request handling capabilities.
  • The request handling logic is encapsulated in a coroutine generated by get_request_handler in fastapi/routing.py.
  • Dependency resolution is a recursive process handled by solve_dependencies in fastapi/dependencies/utils.py.
  • Response serialization is decoupled from the path operation execution, allowing for automatic validation and encoding via serialize_response.
  • FastAPI uses AsyncExitStack at multiple levels (middleware and route handler) to manage the lifecycle of dependencies and background tasks.

FastAPI OpenAPI and Parameter Data Model

This data model diagram illustrates the relationships between FastAPI's OpenAPI specification models, security schemes, and request parameter definitions.

OpenAPI Specification Models

The core of the OpenAPI generation is the OpenAPI class, which aggregates metadata about the API. It contains an Info object for general API details and a collection of PathItem objects representing API endpoints. Each PathItem defines various Operation objects (GET, POST, etc.), which in turn define their expected Parameter and RequestBody structures. The Components class serves as a registry for reusable schemas and Security Schemes and Authentication definitions.

Security Schemes

FastAPI provides security utilities that map directly to OpenAPI security schemes. The OAuth2 security class (from fastapi.security.oauth2) wraps an OpenAPI OAuth2 model to define how authentication flows (like password or authorization code) are represented in the generated documentation. Subclasses like OAuth2PasswordBearer provide specific implementations for common flows.

Request Parameters and Dependencies

FastAPI uses a hierarchy of parameter classes to define how data is extracted from requests.

  • Param is the base for Path, Query, Header, and Cookie parameters.
  • Body is the base for Form and File parameters.
  • Depends and Security define the dependency injection system, where Security adds support for OAuth2 scopes.
  • The File parameter specifically interacts with the UploadFile data structure, which provides an async interface for handling uploaded file data.

The diagram uses standard ER notation to show composition and logical inheritance relationships between these domain entities.

Key Architectural Findings:

  • OpenAPI models in fastapi.openapi.models strictly follow the OpenAPI 3.1.0 specification using Pydantic models.
  • Security classes in fastapi.security act as bridges between runtime dependency injection and OpenAPI metadata generation.
  • Parameter classes in fastapi.params (Path, Query, Body, etc.) inherit from Pydantic's FieldInfo to integrate with Pydantic's validation logic.
  • UploadFile is a specialized data structure that wraps Starlette's UploadFile to provide Pydantic-compatible validation and async file operations.
  • The Depends and Security classes are the foundation of FastAPI's dependency injection system, with Security extending Depends to include OAuth2 scope requirements.

FastAPI Application Lifespan States

This state diagram illustrates the lifecycle of a FastAPI application, from its initial construction to its final termination.

The process begins with the Initialization phase, where the FastAPI instance is created and its default configuration (like OpenAPI and documentation routes) is set up via the setup() method.

Once the application is started by an ASGI server (like Uvicorn), it enters the Lifespan Startup phase. Here, the application executes its startup logic. This can be either the modern lifespan context manager (code before the yield) or the legacy on_startup event handlers, which are wrapped in a _DefaultLifespan class for backward compatibility.

After successful startup, the application transitions to the Running state, where it is ready to serve HTTP and WebSocket requests. During this state, the application's state object is available for sharing data across requests.

When the server receives a shutdown signal (like SIGTERM), the application enters the Lifespan Shutdown phase. It executes the teardown logic (code after the yield in the lifespan context manager or on_shutdown handlers). Finally, the application reaches the Terminated state and the process ends.

The diagram also accounts for potential failures during the startup phase, which lead to a Startup Failed state, preventing the application from serving requests.

Key Architectural Findings:

  • FastAPI uses Starlette's lifespan protocol implementation, which follows the ASGI specification.
  • The lifespan parameter in FastAPI accepts an asynchronous context manager that handles both startup and shutdown.
  • Legacy on_startup and on_shutdown event handlers are still supported and are internally managed by a _DefaultLifespan context manager.
  • Lifespan contexts can be nested and merged when using include_router, allowing sub-routers to have their own lifecycle logic.
  • The application state can be initialized during the startup phase of the lifespan and is then accessible throughout the application's life.
  • The setup() method is called during __init__ to register default routes for OpenAPI and interactive documentation (Swagger UI/ReDoc).