Skip to content

2025 11 21 From Passive FastAPI Developer to Real FastAPI Engineer Part 1: ASGI


title: From Passive FastAPI Developer to Real FastAPI Engineer- Part 1: ASGI date: 2025-11-21 original_url: https://levelup.gitconnected.com/from-passive-fastapi-developer-to-real-fastapi-engineer-part-1-asgi-059a588a54ae?source=rss-e0d89d1af01d------2


Photo by Kaue Barbier: https://www.pexels.com/photo/28182842/

Understanding ASGI by Breaking Down an HTTP Request

Modern Python web frameworks feel effortless- you write a function, return some JSON, and boom: a web app. But underneath that smooth layer lies a ton of complexity: raw bytes over TCP, state machines, protocols, concurrency, and error-prone details you never want to touch.

ASGI exists to shield you from that pain. Let’s break an HTTP request down and see how ASGI fits into the picture.

What is ASGI?

ASGI (Asynchronous Server Gateway Interface) is a Python specification that defines how web servers communicate with asynchronous Python applications.

Official spec: https://asgi.readthedocs.io/en/latest/

You can think of it as the evolution of WSGI, designed for modern async apps, HTTP/2, and WebSockets.

Why Do We Need ASGI?

Inside every web server, there are three conceptual layers:

Transport  ->  Protocol  ->  Application Logic  
TCP/SSL        HTTP/WS        Your FastAPI code

The problem:
If every framework had to re-implement TCP handling, HTTP parsing, connection lifecycle, etc., we’d live in a world of endless duplicated code and subtle bugs.

ASGI proposes a clean split into two Python components:

  1. Protocol Server (e.g., Uvicorn, Hypercorn)
  • Handles raw network I/O
  • Transforms bytes into structured ASGI events

2. Application (e.g., Starlette, FastAPI, custom ASGI apps)

  • Receives events like http.request
  • Returns events like http.response.start and http.response.body

This “bridge” is ASGI:

Protocol Server  <---- ASGI ---->  Application

A Quick Timeline of Request Interfaces

Year Spec Notes:

1993 CGI Process-per-request. Ancient, slow.

2003 WSGI (PEP 333) Standardized sync Python apps.

2010 WSGI 1.0.1 (PEP 3333) Updated for Python 3.

2016 ASGI Async, event-based design.

2019 ASGI 3.0 Modern form used today.

Why WSGI Wasn’t Enough

WSGI apps are synchronous and take exactly two parameters:

def app(environ, start_response):  
    start_response("200 OK", [("Content-Type", "text/plain")])  
    return [b"hello"]

This works for HTTP/1.1 but fails for:

  • concurrency
  • streaming
  • long-lived connections
  • WebSockets

WSGI can’t represent async behavior or event-driven protocols.

ASGI’s Core Idea

An ASGI application is an async callable :

async def app(scope, receive, send):  
    ...
  • scope → Metadata about the connection (type, path, headers, etc.)
  • receive() → Wait for events from server (e.g., request body chunks)
  • send() → Emit events back (response start, response body, WebSocket messages)

This event system is the real power. It makes communication flexible and supports full-duplex protocols.

A Minimal ASGI App (Raw)

async def app(scope, receive, send):  
    assert scope["type"] == "http"

await send({  
        "type": "http.response.start",  
        "status": 200,  
        "headers": [(b"content-type", b"text/plain")],  
    })  
    await send({  
        "type": "http.response.body",  
        "body": b"Hello from raw ASGI!",  
    })

Run it with Uvicorn:

uvicorn example:app

HTTP Request Flow in WSGI vs ASGI

WSGI Flow (Sync)

Client  
  |  
HTTP Request  
  |  
WSGI Server parses bytes  
  |  
(environ, start_response)  
  |  
WSGI App  
  |  
Iterables of bytes  
  |  
WSGI Server → HTTP Response

No events. No async. No real-time messaging.

ASGI Flow (Event-Based, Async)

Client  
  |  
Raw Bytes  
  |  
Protocol Server (Uvicorn / Daphne)  
  |  
ASGI Event: "http.request", "http.disconnect"  
  |  
async app(scope, receive, send)  
  |  
Your app emits events:  
  - "http.response.start"  
  - "http.response.body"  
  - "websocket.accept"  
  - "websocket.send"

This model is more general, flexible, and future-proof.

Why ASGI Matters

1. Concurrency

Async I/O = thousands of simultaneous connections.

2. WebSockets Support

WSGI can’t do WebSockets.
ASGI makes WebSockets just another protocol supported by events.

3. Full-Duplex Communication

Send and receive independently- essential for:

  • WebSockets
  • HTTP streaming
  • Server-Sent Events
  • Background events

4. Protocol Independence

ASGI officially supports:

  • http
  • websocket
  • lifespan (startup/shutdown events)

More protocols can be added without rewriting frameworks.

A Tiny Diagram: ASGI in FastAPI

      ┌──────────────────┐  
      │   Your FastAPI   │  
      │      App         │  
      └────────┬─────────┘  
               │  ASGI callable  
               ▼  
        ASGI Interface  
               ▲  
               │ events  
      ┌────────┴─────────┐  
      │   Uvicorn Server │  
      │ (Protocol Layer) │  
      └──────────────────┘

You “inject” your application into the protocol server.
The server handles all low-level details- your app just reacts to events.

Final Summary

ASGI gives us:

  • async concurrency
  • flexible event-driven communication
  • WebSocket support
  • protocol independence
  • clean separation of logic vs transport
  • a standard interface for modern Python web servers

It’s the foundation that makes Starlette and FastAPI so fast and the reason you never have to manipulate raw HTTP bytes yourself.

References:


From Passive FastAPI Developer to Real FastAPI Engineer- Part 1: ASGI was originally published in Level Up Coding on Medium, where people are continuing the conversation by highlighting and responding to this story.