如何编写符合 ASGI 标准的中间件(同时保持与框架无关)?

exh*_*uma 6 python asgi

我们目前正在维护用多个 HTTP 框架(Flask、aiohttp 和 FastAPI)编写的代码。重写它们以便它们都使用相同的框架目前是不可行的。我想在这些应用程序之间共享一些代码,这些代码非常适合中间件(日志记录配置、监控、身份验证等)。

最初的实现是通过子类化 Flask 来完成的,并且在所有基于 Flask 的应用程序中运行得非常好。但它在 aiohttp 或 FastAPI 中无法使用。

创建一个与框架无关的实现是可行的(理论上),今天早上我采用了一个更简单的案例,并成功地将其转换为 WSGI 中间件,并且能够将其集成到 Flask 应用程序中。

但 ASGI 给我带来了一些麻烦,因为没有太多关于纯 ASGI中间件的文档。所有示例都展示了如何为其框架编写中间件

ASGI 官方文档在该主题上也非常“精简”。据我所知,它应该看起来像这样(附带问题:“传递给构造函数的第二个参数是什么?”):

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)
Run Code Online (Sandbox Code Playgroud)

我以Starlette TimingMiddleware作为灵感,但我无法将它与aiohttp. 可能是因为他们的实现略有不同。

考虑到 ASGI 规范中有一个中间件部分,并且两者都aiohttp实现Starlette了该规范,难道不应该有一种方法来编写一个可以在两者中工作的中间件吗?

如果是的话,我错过了什么?

小智 1

没有办法让相同的中间件支持所有三个框架。