a2wsgi
Pure-Python middleware to convert WSGI apps to ASGI and ASGI apps to WSGI.
Repository Health
Technical Analysis
a2wsgi is a small, pure-Python library that bridges the WSGI and ASGI web application protocols in both directions. Its WSGIMiddleware wraps a synchronous WSGI app so it can run under an ASGI server, while its ASGIMiddleware wraps an async ASGI app so it can be deployed on existing WSGI infrastructure.
Its key advantage over other converters is streaming: a2wsgi never accumulates full request or response bodies in memory, so it avoids the memory blow-ups that buffering-based adapters can hit on large payloads. It depends only on the standard library and exposes the original scope/environ across the boundary.
What You Get
- WSGIMiddleware to run a WSGI app under any ASGI server
- ASGIMiddleware to run an ASGI app under any WSGI server
- Streaming request/response handling that never buffers full bodies in memory
- Tunable concurrency via worker thread pool and send-queue size, plus optional custom event loop and background-task wait timeout
- Access to the original protocol context through scope[‘wsgi_environ’] and environ[‘asgi.scope’]
Common Use Cases
- Migrating a legacy WSGI app (Django, Flask, Pyramid) toward an ASGI stack incrementally
- Deploying an ASGI app (FastAPI, Starlette, Quart) on existing WSGI hosting
- Mounting a WSGI sub-application inside an ASGI application
- Avoiding memory limits when proxying large uploads or streamed responses across the protocol boundary
Under The Hood
Architecture
The library is intentionally tiny: a2wsgi/wsgi.py implements WSGIMiddleware and a2wsgi/asgi.py implements ASGIMiddleware, with wsgi_typing.py and asgi_typing.py providing precise protocol type definitions and a py.typed marker for downstream type checking. WSGIMiddleware runs the synchronous app in a bounded thread pool and streams chunks back through a size-limited queue; ASGIMiddleware drives the async app on an event loop and translates its send/receive events into a WSGI iterable, bridging the environ and scope both ways.
Tech Stack 100% Python with zero runtime dependencies beyond the standard library. Packaging and tooling use PDM (pyproject.toml, pdm.lock). A benchmark harness (benchmark.py) compares throughput against uvicorn’s and asgiref’s converters.
Code Quality
The code is fully type-annotated with dedicated typing modules for both protocols, ships a test suite under tests/, and includes a benchmark script — appropriate rigor for middleware that sits on a hot request path. The surface area is deliberately minimal, which keeps behavior easy to audit.
API Design
The API is essentially two callables: wrap your app in WSGIMiddleware(app) or ASGIMiddleware(app) and you are done. Tuning is optional and discoverable through keyword arguments (workers, send_queue_size, wait_time, loop), and cross-protocol context is reachable without extra plumbing. There is almost no boilerplate to get started.