a2wsgi
a2wsgi is a Python library that enables seamless conversion between WSGI (Web Server Gateway Interface) and ASGI (Asynchronous Server Gateway Interface) applications. It acts as a middleware, allowing you to run WSGI apps on ASGI servers or ASGI apps on WSGI servers. The current version is 1.10.10, and it maintains an active release schedule with frequent minor updates, primarily focusing on bug fixes and performance improvements.
Common errors
-
ModuleNotFoundError: No module named 'a2wsgi'
cause The 'a2wsgi' package is not installed in the Python environment.fixInstall the package using 'pip install a2wsgi'. -
ImportError: cannot import name 'WSGIMiddleware' from 'a2wsgi'
cause The 'a2wsgi' package is installed, but the import statement is incorrect or the package version does not include 'WSGIMiddleware'.fixEnsure the import statement is correct: 'from a2wsgi import WSGIMiddleware'. If the error persists, update the package using 'pip install --upgrade a2wsgi'. -
TypeError: 'WSGIMiddleware' object is not callable
cause An instance of 'WSGIMiddleware' is being called as a function, but it is not designed to be called directly.fixEnsure that 'WSGIMiddleware' is used to wrap a WSGI application correctly: 'asgi_app = WSGIMiddleware(wsgi_app)'. -
AttributeError: module 'a2wsgi' has no attribute 'ASGIMiddleware'
cause The 'ASGIMiddleware' attribute is not present in the 'a2wsgi' module, possibly due to an outdated package version.fixUpdate the 'a2wsgi' package to the latest version using 'pip install --upgrade a2wsgi'. -
ValueError: WSGI application must be a callable object
cause The object passed to 'WSGIMiddleware' is not a valid WSGI application.fixEnsure that the WSGI application passed to 'WSGIMiddleware' is a callable object, typically a function or a class with a '__call__' method.
Warnings
- gotcha WSGI applications converted to ASGI via `ASGIMiddleware` still execute synchronously. If your wrapped WSGI app performs blocking I/O operations (e.g., database calls, network requests) directly, it will block the entire ASGI event loop, negating the performance benefits of an async server.
- gotcha When `ASGIMiddleware` converts an ASGI request with a large body to WSGI, it must buffer the entire request body into memory before passing it via `wsgi.input` to the WSGI application. This can lead to significant memory consumption for large file uploads or extensive POST data.
- gotcha When chaining multiple middleware, the order of `a2wsgi` conversion is crucial. You should convert the innermost application to the type expected by the next middleware in the chain. Incorrect ordering can lead to interface mismatches.
Install
-
pip install a2wsgi
Imports
- ASGIMiddleware
from a2wsgi import ASGIMiddleware
- WSGIMiddleware
from a2wsgi import WSGIMiddleware
Quickstart
from a2wsgi import ASGIMiddleware
# A simple synchronous WSGI application
def wsgi_app(environ, start_response):
status = '200 OK'
headers = [('Content-type', 'text/plain; charset=utf-8')]
start_response(status, headers)
return [b"Hello from WSGI!\nRequest Path: " + environ.get('PATH_INFO', '/').encode()]
# Convert the WSGI app to an ASGI app
asgi_app = ASGIMiddleware(wsgi_app)
# To run this converted ASGI app using an ASGI server like Uvicorn:
# 1. Save this code as 'app.py'
# 2. Install uvicorn: pip install uvicorn
# 3. Run from your terminal: uvicorn app:asgi_app --reload
# Then open http://127.0.0.1:8000/ in your browser.
print("WSGI application 'wsgi_app' successfully wrapped as an ASGI application 'asgi_app'.")
print("To serve it, use an ASGI server like Uvicorn (e.g., 'uvicorn app:asgi_app').")