如何将自定义装饰器添加到FastAPI路由? [英] How to add a custom decorator to a FastAPI route?
问题描述
我想向我的端点添加一个 auth_required
装饰器.(请考虑这个问题是关于装饰器,而不是中间件)
I want to add an auth_required
decorator to my endpoints.
(Please consider that this question is about decorators, not middleware)
所以一个简单的装饰器看起来像这样:
So a simple decorator looks like this:
def auth_required(func):
def wrapper(*args, **kwargs):
if user_ctx.get() is None:
raise HTTPException(...)
return func(*args, **kwargs)
return wrapper
所以有2种用法:
@auth_required
@router.post(...)
或
@router.post(...)
@auth_required
第一种方法不起作用,因为 router.post
创建了一个保存到APIRouter对象的 self.routes
中的路由器.第二种方法行不通,因为它无法验证pydantic对象.对于任何请求模型,它都表示 args丢失,缺少kwargs
.
The first way doesn't work because router.post
creates a router that saved into self.routes
of APIRouter object. The second way doesn't work because it fails to verify pydantic object. For any request model, it says missing args, missing kwargs
.
所以我的问题是-如何将任何装饰器添加到FastAPI端点?我应该进入 router.routes
并修改现有端点吗?还是使用一些 functools.wraps
之类的函数?
So my question is - how can I add any decorators to FastAPI endpoints? Should I get into router.routes
and modify the existing endpoint? Or use some functools.wraps
like functions?
推荐答案
如何将任何装饰器添加到FastAPI端点?
How can I add any decorators to FastAPI endpoints?
如您所说,您需要使用 @ functools.wraps(...)
-(PyDoc)装饰器,
As you said, you need to use @functools.wraps(...)
--(PyDoc) decorator as,
from functools import wraps
from fastapi import FastAPI
from pydantic import BaseModel
class SampleModel(BaseModel):
name: str
age: int
app = FastAPI()
def auth_required(func):
@wraps(func)
async def wrapper(*args, **kwargs):
return await func(*args, **kwargs)
return wrapper
@app.post("/")
@auth_required # Custom decorator
async def root(payload: SampleModel):
return {"message": "Hello World", "payload": payload}
此方法的主要警告是,您不能在包装器中访问 request
对象,并且我认为这是您的主要意图.
The main caveat of this method is that you can't access the request
object in the wrapper and I assume it is your primary intention.
如果您需要访问请求,则必须将参数添加为路由器功能,
If you need to access the request, you must add the argument to the router function as,
from fastapi import Request
@app.post("/")
@auth_required # Custom decorator
async def root(request: Request, payload: SampleModel):
return {"message": "Hello World", "payload": payload}
我不确定FastAPI中间件怎么了,毕竟 @ app.middleware(...)
装饰器.
这篇关于如何将自定义装饰器添加到FastAPI路由?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!