[英]How to write a custom FastAPI middleware class
I have read FastAPI's documentation about middlewares (specifically, the middleware tutorial , the CORS middleware section and the advanced middleware guide), but couldn't find a concrete example of how to write a middleware class which you can add using the add_middleware
function (in與使用裝飾器添加的基本中間件 function 相比)在此站點上也沒有。
我更喜歡在基於應用的裝飾器上使用add_middleware
的原因是,我想在共享庫中編寫一個中間件,供幾個不同的項目使用,因此我不能將它綁定到特定的FastAPI
實例。
所以我的問題是:你是怎么做到的?
由於 FastAPI 實際上是下面的Starlette ,因此您可以使用BaseHTTPMiddleware
來實現中間件 class(您可能也想看看這篇文章)。 下面給出了相同方法的兩個變體,其中add_middleware()
function 用於添加中間件 class。
中間件.py
from fastapi import Request
class MyMiddleware:
def __init__(
self,
some_attribute: str,
):
self.some_attribute = some_attribute
async def __call__(self, request: Request, call_next):
# do something with the request object
content_type = request.headers.get('Content-Type')
print(content_type)
# process the request and get the response
response = await call_next(request)
return response
應用程序.py
from fastapi import FastAPI
from middleware import MyMiddleware
from starlette.middleware.base import BaseHTTPMiddleware
app = FastAPI()
my_middleware = MyMiddleware(some_attribute="some_attribute_here_if_needed")
app.add_middleware(BaseHTTPMiddleware, dispatch=my_middleware)
中間件.py
from fastapi import Request
from starlette.middleware.base import BaseHTTPMiddleware
class MyMiddleware(BaseHTTPMiddleware):
def __init__(
self,
app,
some_attribute: str,
):
super().__init__(app)
self.some_attribute = some_attribute
async def dispatch(self, request: Request, call_next):
# do something with the request object, for example
content_type = request.headers.get('Content-Type')
print(content_type)
# process the request and get the response
response = await call_next(request)
return response
應用程序.py
from fastapi import FastAPI
from middleware import MyMiddleware
app = FastAPI()
app.add_middleware(MyMiddleware, some_attribute="some_attribute_here_if_needed")
@Error - Syntactical Remorse 引發的BaseHTTPMiddleware 錯誤的一個潛在解決方法是對中間件定義使用部分並使用函數式方法,這似乎至少對我有用:
from typing import Any, Callable, Coroutine
from fastapi import Response
async def my_middleware(request: Request, call_next: Callable, some_attribute: Any) -> Response:
request.state.attr = some_attribute # Do what you need with your attribute
return await call_next(request)
from functools import partial
from fastapi import FastAPI
from middleware import my_middleware
app = FastAPI()
my_custom_middleware: partial[Coroutine[Any, Any, Any]] = partial(my_middleware, some_attribute="my-app")
app.middleware("http")(my_custom_middlware)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.