python - 如何将自定义装饰器添加到 FastAPI 路由?
问题描述
我想为auth_required
我的端点添加一个装饰器。(请考虑这个问题是关于装饰器,而不是中间件)
所以一个简单的装饰器看起来像这样:
def auth_required(func):
def wrapper(*args, **kwargs):
if user_ctx.get() is None:
raise HTTPException(...)
return func(*args, **kwargs)
return wrapper
所以有两种用法:
@auth_required
@router.post(...)
或者
@router.post(...)
@auth_required
第一种方法不起作用,因为router.post
创建了一个保存到self.routes
APIRouter 对象中的路由器。第二种方法不起作用,因为它无法验证 pydantic 对象。对于任何请求模型,它都说missing args, missing kwargs
.
所以我的问题是 - 如何将任何装饰器添加到 FastAPI 端点?我应该进入router.routes
并修改现有端点吗?或者使用一些functools.wraps
类似的功能?
解决方案
如何将任何装饰器添加到 FastAPI 端点?
正如你所说,你需要使用@functools.wraps(...)
--(PyDoc)装饰器,
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
包装器中的对象,我认为这是您的主要意图。
如果您需要访问请求,则必须将参数添加到路由器函数中,
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(...)
也是一个装饰器。
推荐阅读
- web-scraping - Jsoup 解析 Youtube 页面
- c# - Unity Collider - Box Collider 和 Mesh Renderer 在碰撞后移动
- paypal - PayPal next_billing_time 总是返回 10:00:00Z
- arrays - 如何在数组 Golang 中找到不重复的项目
- javascript - 如何使用 JavaScript 将作为数组的字符串转换为数组
- terraform - 当 Terraform 模板中的元组为空时,如何获取默认值?
- excel - 停止宏以在导入的数据中添加标题(标题必须手动添加,因为每次都有不同的库号)
- mongodb - MongoDB findOneAndUpdate 嵌套对象
- json - 如何使用组合从 SwiftUI 中的 URL 解析单个 JSON 对象?
- sql - SQL 重新排列行