我在使用 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))
问题很可能在于您对创建的每个端点使用相同的
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"])