如何在类中使用FastAPI创建路由

问题描述

因此,我需要在一个类中包含一些路由,但是route方法需要具有self attr(以访问该类的属性)。 但是,FastAPI然后假定self是其自己的必需参数,并将其作为查询参数放入

这就是我所拥有的:

app = FastAPI()
class Foo:
    def __init__(y: int):
        self.x = y

    @app.get("/somewhere")
    def bar(self): return self.x

但是,除非您转到422,否则它将返回/somewhere?self=something。问题在于self是str,因此无用。

我需要某种方式,使我仍然可以访问self而不必将其作为必需参数。

解决方法

要创建基于类的视图,可以使用@cbv中的fastapi-utils装饰器。使用它的动机:

停止在相关端点的签名中反复重复相同的依赖项。

您的示例可以这样重写:

from fastapi import Depends,FastAPI
from fastapi_utils.cbv import cbv
from fastapi_utils.inferring_router import InferringRouter


def get_x():
    return 10


app = FastAPI()
router = InferringRouter()  # Step 1: Create a router


@cbv(router)  # Step 2: Create and decorate a class to hold the endpoints
class Foo:
    # Step 3: Add dependencies as class attributes
    x: int = Depends(get_x)

    @router.get("/somewhere")
    def bar(self) -> int:
        # Step 4: Use `self.<dependency_name>` to access shared dependencies
        return self.x


app.include_router(router)
,

我不喜欢这样做的标准方式,所以我编写了自己的库。你可以这样安装:

$ pip install cbfa

这是一个如何使用它的例子:

from typing import Optional
from fastapi import FastAPI
from pydantic import BaseModel
from cbfa import ClassBased


app = FastAPI()
wrapper = ClassBased(app)

class Item(BaseModel):
    name: str
    price: float
    is_offer: Optional[bool] = None

@wrapper('/item')
class Item:
    def get(item_id: int,q: Optional[str] = None):
        return {"item_id": item_id,"q": q}

    def post(item_id: int,item: Item):
        return {"item_name": item.name,"item_id": item_id}

请注意,您不需要为每个方法包装装饰器。根据它们在 HTTP 协议中的用途来命名方法就足够了。整个类都变成了装饰器。

,

您从类中的FastAPI继承,并将FastAPI装饰器用作方法调用(我将使用APIRouter进行显示,但您的示例应该可以运行):

class Foo(FastAPI):
    def __init__(y: int):
        self.x = y

        self.include_router(
            health.router,prefix="/api/v1/health",)
,

我将路由放到 def __init__。它正常工作。 示例:

from fastapi import FastAPI
from fastapi.responses import HTMLResponse

class CustomAPI(FastAPI):
    def __init__(self,title: str = "CustomAPI") -> None:
        super().__init__(title=title)

        @self.get('/')
        async def home():
            """
            Home page
            """
            return HTMLResponse("<h1>CustomAPI</h1><br/><a href='/docs'>Try api now!</a>",status_code=status.HTTP_200_OK)

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...