How an HTTP request reaches your Python application
standardadvancedA request crosses at least four hops before application code runs: the reverse proxy (nginx/an LB) terminates TLS and forwards the request; the WSGI/ASGI server (Gunicorn/Uvicorn) translates raw HTTP into the interface your framework expects; a worker process or thread actually picks up that request; and only then does your view/handler function run. Naming all four in order, without skipping the proxy or the server, is the actual "how does a request reach my app" answer.
Think of it as
A request is a passenger going through four checkpoints, not walking straight into the building. The reverse proxy is the front gate (TLS, routing, maybe caching or rate limiting). The WSGI/ASGI server is the reception desk that translates "someone arrived" into the specific interface (a WSGI environ dict, or an ASGI scope/receive/send) your framework knows how to read. A worker is the specific staff member assigned to handle this one visitor. Only after all three does the visitor actually reach your view function's desk.
What we're doing: Model each hop as a step that transforms a request object, and print the transformation happening at each stage to make all four hops explicit in order.
- 1
- reverse_proxy is where TLS termination and client-IP forwarding actually happen — application code never sees raw TLS at all.
- 5
- wsgi_asgi_server is the translation step — it reshapes the request into the "scope" shape a framework's routing actually expects, distinct from both the proxy before it and the worker after it.
- 9
- worker_pickup is a separate hop from the server itself — which specific worker (process or task) ends up handling this request is decided here, not at hop 2.
GET /api/orders/42 handled by worker 3
tls_terminated at hop 1: TrueWhy this works: Each function receives the previous hop's output and adds exactly one new piece of information — tls_terminated at the proxy, a reshaped scope at the server, a worker_id at pickup — modeling that a request is genuinely transformed at each of four distinct layers before framework_view (application code) ever runs, not handed directly from the client to the view function.
Remember: Four hops, in order: reverse proxy (TLS, routing) -> WSGI/ASGI server (HTTP -> framework interface) -> worker (picks up this request) -> framework routing -> your view function. Skipping the middle two hops is the most common gap in this explanation.
See also: reverse proxy and load balancer · wsgi vs asgi · gunicorn · uvicorn · worker and thread models

