We're currently maintaining code written in several HTTP frameworks (Flask, aiohttp and FastAPI). Rewriting them so they all use the same framework is currently not feasible. There's some code that I'd like to share across those applications and that would be very well suited for middleware (logging-config, monitoring, authentication, ...).
The initial implementation was done by subclassing Flask and worked really well across all Flask-based apps. But it's unusable in aiohttp or FastAPI.
Creating a framework-agnostic implementation is doable (theoretically) and this morning I've taken one of the simpler cases and successfully converted it to WSGI middleware and am able to integrate it in the Flask applications.
But ASGI is giving me some trouble because there's not much documentation out there for pure ASGI middleware. All the examples show how middleware is written for their framework.
The official ASGI docs is also really really "skinny" on that topic. From what I can tell, it should look something like this (side-questions: "What's the second argument passed into the constructor?"):
class MyMiddleware:
def __init__(self, app, something) -> None:
self.app = app
self.something = something # <- what is this second argument?
async def __call__(self, scope, receive, send):
print("Hello from the Middleware")
await self.app(scope, receive, send)
I took Starlette TimingMiddleware as inspiration, but I am unable to integrate it with aiohttp
. Probably because their implementation is slightly different.
Considering that there is a section of middleware in the ASGI specification, and that both aiohttp
and Starlette
implement that spec, shouldn't there be a way to write a middleware that works in both?
If yes, what am I missing?
There is no way to have the same middleware support all three frameworks.