Request Lifecycle
This page traces what happens from the moment a browser sends an HTTP request to when it receives a JSON response. Understanding this flow helps you know where to add new behavior and where to look when something breaks.
Request flow
sequenceDiagram
participant Browser
participant FastAPI as FastAPI (app/main.py)
participant Router as Route module (app/api/)
participant AuthDep as Auth dependency (app/auth/dependencies.py)
participant Service as Domain service (app/projects/, app/auth/, etc.)
participant Store as Storage (app/storage/)
Browser->>FastAPI: HTTP request to /v1/...
FastAPI->>FastAPI: CORS check, logging middleware
FastAPI->>Router: Route matched
alt Protected endpoint
Router->>AuthDep: require_current_user()
AuthDep->>AuthDep: Extract Bearer token from header
AuthDep->>AuthDep: Validate token (custom HMAC or Cognito JWT)
AuthDep-->>Router: CurrentUser object
end
Router->>Service: Call domain service method
Service->>Store: Read or write data (Postgres / S3 / JSON)
Store-->>Service: Result
Service-->>Router: Domain object or error
Router-->>Browser: JSON response (200) or error envelope (4xx/5xx)
Key files
app/main.py— Creates the FastAPI app, sets up CORS, attaches the JSON logging middleware, and mounts the API router. Also registers startup/shutdown hooks for Codex container cleanup.app/api/routes.py— Imports every route module and includes them under/v1. This is where you'd add a new route group.app/auth/dependencies.py— Provides therequire_current_userFastAPI dependency. Route handlers declare this as a parameter to require authentication.app/core/settings.py— Loaded at startup. Every configuration decision (auth mode, storage backend, etc.) traces back here.app/core/errors.py— Definesapi_error(), the helper that produces the structured error envelope every route should use for failures.
Authentication
Every protected route declares a dependency on require_current_user. This dependency:
- Reads the
Authorization: Bearer <token>header - In
customauth mode: validates an HMAC-signed local token - In
cognitoauth mode: fetches the Cognito JWKS and validates the JWT signature + claims
If the token is missing or invalid, FastAPI returns 401 before the route handler runs.
Some routes additionally require a specific user group (e.g., operator or root). Group checks happen inside the dependency.
Error shape
All errors, regardless of where they occur, return the same JSON envelope:
{
"schema_version": 1,
"error": {
"code": "not_found",
"message": "Repository abc123 not found",
"retryable": false,
"details": {}
}
}
codeis a stable machine-readable string (use it for branching in frontend code)messageis human-readable (show it in the UI)retryabletells the client whether a retry makes sense (e.g.,truefor transient errors)detailsis optional structured context (e.g., which field failed validation)
Debugging a failed request
Start with the most external check and work inward:
- Did the request reach FastAPI? Check the API logs for the request line.
- Did auth fail? A
401withinvalid_tokencode means the token is bad or missing. A403means the user lacks the required group. - Did the route handler fail? Look for
5xxerrors and the errorcodein the response. - Did a downstream service fail? Check Postgres, S3, SQS, or Cognito. In AWS, check CloudWatch logs.