是否可以将 Path 参数传递到 FastAPI 依赖函数中?

问题描述 投票:0回答:2

是否有 FastAPI“依赖项”来解释路径参数?

我有很多形式的函数:

@app.post("/item/{item_id}/process", response_class=ProcessResponse)
async def process_item(item_id: UUID, session: UserSession = Depends(security.user_session)) -> ProcessResponse:
    item = await get_item(client_id=session.client_id, item_id=item_id)
    await item.process()

一遍又一遍,我需要传入[多个]参数来获取所需的项目,然后再对其进行操作。这是非常重复的并且使得代码非常冗长。我真正想做的是将

item
作为参数传递给该方法。

理想情况下,我想将

get_item
作为依赖项或以某种方式将其嵌入路由器中。这将大大减少重复的逻辑和过于冗长的函数参数。问题在于客户端在路径中传递了一些关键参数。

是否可以将 Path 参数传递到依赖项中,或者在路由器中执行依赖项并传递结果?

python fastapi
2个回答
29
投票

FastAPI 依赖函数可以采用普通端点函数可以采用的任何参数。

因此,在普通端点中,您可以像这样定义路径参数:

from fastapi import FastAPI

app = FastAPI()


@app.get("/items/{item_id}")
async def read_item(item_id):
    return {"item_id": item_id}

现在,如果您想在依赖项中使用该参数,您可以简单地执行以下操作:

from fastapi import Depends, FastAPI

app = FastAPI()

async def my_dependency_function(item_id: int):
    return {"item_id": item_id}


@app.get("/items/{item_id}")
async def read_item(item_id: int, my_dependency: dict = Depends(my_dependency_function)):
    return my_dependency

如果参数存在,参数将简单地传递到依赖函数。您还可以在依赖函数中使用

Path
Query
等内容来定义它们的来源。

它只会分析请求对象来提取这些值。

这是使用 FastAPI 中的

Path
函数的示例:

from fastapi import Depends, FastAPI, Path

app = FastAPI()

async def my_dependency_function(item_id: int = Path(...)):
    return {"item_id": item_id}


@app.get("/items/{item_id}")
async def read_item(my_dependency: dict = Depends(my_dependency_function)):
    return my_dependency

对于将其实现为路由器中的依赖项的担忧,您可以在创建路由器时执行以下操作:

items_router = APIRouter(
    prefix="/items",
    tags=["items"],
    dependencies=[Depends(my_dependency_function)],
)

或者您可以在应用程序上运行

include_router
时执行此操作,例如:

app.include_router(
    items_router,
    prefix="/items",
    dependencies=[Depends(my_dependency_function)],
)

有关依赖项的更多信息和更多类似示例,请参阅 https://fastapi.tiangolo.com/tutorial/dependency/


0
投票

也可以通过基于类的方法实现相同的目标

首先,像这样创建你的依赖项

class ItemIdExtractor:
    async def __call__(self, item_id: int = Path()) -> int | None:
        # DO SOMETHING HERE IF NEEDED. MAYBE VALIDATE ETC.
        return item_id


ItemIdDep = Depends(ItemIdExtractor())

然后你可以在任何你想要的路径操作中使用它

@app.get("/items/{item_id}")
async def retrieve_item(item_id: int = ItemIdDep):
    print(item_id)
    return Response(status_code=status.HTTP_200_OK)
© www.soinside.com 2019 - 2024. All rights reserved.