WSGI & ASGI Explained
Underneath Flask, Django, FastAPI - every Python web framework - there's one small contract that lets a
web server and your Python code talk to each other. For synchronous frameworks it's WSGI; for async
ones it's ASGI. Almost nobody learns these directly, which is exactly why "how does flask run
actually serve a request?" feels like magic. It isn't: a WSGI app is a plain Python callable the server
invokes, and an ASGI app is an async callable. Once you've written each by hand - in a dozen lines, with
no framework - every framework reads as conveniences over that callable.
This is a roots guide. You'll rarely write raw WSGI/ASGI apps in a real job (frameworks exist for
good reasons), but understanding them demystifies a pile of things at once: why you run gunicorn or
uvicorn in production, what "middleware" really is, why FastAPI is async and Flask isn't, and how the
whole Python web stack fits together. We build it bare-metal first, then point at the frameworks and watch
the shapes line up.
📝 This assumes Python (functions, async/await - Python From Zero) and a grasp of HTTP (HTTP, Explained). It's the Python parallel to The Servlet API (Java's equivalent foundation) and is most useful after you've used Flask or FastAPI and want to see beneath them. Examples are shown with their output rather than run on the page.
How to read this
Short and foundational - read in order. It builds a bare WSGI app, then a bare ASGI app, then maps both onto the frameworks you know. Phases carry difficulty badges.
The phases
- What WSGI Is 🟢 - the contract between a web server and a Python app, and the problem it solved.
- A WSGI App From Scratch 🟡 - write one in a dozen lines with no framework, and see what Flask is underneath.
- The WSGI Server & Middleware 🟡 - gunicorn/uWSGI run your app; middleware wraps it - the root of framework "middleware."
- Why ASGI Exists 🔴 - WSGI is synchronous; async (websockets, high concurrency) needs a new contract.
- An ASGI App & the Servers 🟡 - a bare ASGI app, uvicorn, and how FastAPI/Starlette sit on top.
- From Protocol to Framework 🟢 - Flask = a WSGI app, FastAPI = an ASGI app; the whole stack, seen.
Once you've seen the callable, "a Python web framework" reads as "conveniences over a WSGI or ASGI app." The magic was always this contract.