如何将自定义装饰器添加到FastAPI路由? [英] How to add a custom decorator to a FastAPI route?

查看:208
本文介绍了如何将自定义装饰器添加到FastAPI路由?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想向我的端点添加一个 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆