如何为 Pydantic 模型列表动态创建 FastAPI 路由/处理程序?

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

我在使用 FastAPI 时遇到问题,尝试动态定义路由。看来最终定义的路由/处理程序会覆盖所有之前的路由/处理程序(见下图)

情况:我有很多 Pydantic 模型作为列表(从

models.py
导入:在示例中进行了简化),并且想为每个模型创建一个 GET 端点。

类似这样的东西(我的应用程序更复杂 - 它的结构是有原因的 - 但我已将其简化为这样,以便找到仍然出现的问题):

# models.py

class Thing(BaseNode):
    value: str

class Other(BaseNode):
    value: str

model_list = [Thing, Other]



# app.py
from models import model_list

app = FastApi()


# Iterate over the models list and define a get function
for model in models_list:

    @app.get(f"/{model.__name__.lower()}")
    def get() -> str:
         print(model.__name__)
         return f"Getting {model.__name__)

我显然做错了什么(或者 FastAPI 以某种奇怪的方式引用处理程序函数......通过模块/函数名称(?),因此每次迭代都会重新定义 get() 函数?)任何想法,或者更好的方式来构建这个? (我无法为每个模型手动编写一个新函数!)

谢谢!

更新: 更新:

如果我在另一个函数中定义

get()
函数,它就可以工作:

for model in models_list:
     def get(model):
         def _get():
             print("Getting", model)
                
             return f"Getting {model.__name__}"
         return _get

     app.get(.get(f"/{model.__name__.lower()}", name=f"{model.__name__}.View")(get(model))

python fastapi url-routing pydantic starlette
1个回答
0
投票

问题很可能在于您对创建的每个端点使用相同的

model
引用,因此,它始终被分配 for 循环中给出的最后一个值。

您应该使用返回内部函数的辅助函数,如此答案的选项 2 所示。

示例

from fastapi import FastAPI, APIRouter, Request
from pydantic import BaseModel


class One(BaseModel):
    value: str


class Two(BaseModel):
    value: str


app = FastAPI()
models = [One, Two]


def create_endpoint(m_name: str):
    async def endpoint(request: Request):
        print(request.url)
        return f"You called {m_name}"
    return endpoint


for m in models:    
    app.add_api_route(f"/{m.__name__.lower()}", create_endpoint(m.__name__), methods=["GET"])
© www.soinside.com 2019 - 2024. All rights reserved.