FastAPI多依赖各带Pydantic请求体时Swagger仅显单个schema如何解决
问题根因
- FastAPI的OpenAPI生成逻辑默认每个路径操作仅会生成一个请求体Schema,当你注入多个带请求体的依赖时,只会保留第一个依赖的请求体定义,所以Swagger只会展示parent1相关字段
- 你当前的代码实际运行也会出错:当请求同时携带
parent1和parent2字段时,第一个依赖function_1解析RequestBody1时,会因为存在未定义的parent2字段触发Pydantic校验报错 - 额外小问题:你代码里
dict(request_1.items() + request_2.items())的写法在Python3中不生效,Python3的字典视图无法直接相加,建议使用{**request_1, **request_2}或者Python3.9+支持的request_1 | request_2写法
最优解决方案
通过Pydantic多继承定义合并的请求体模型,完全适配你的预期Swagger展示效果,同时解决运行时报错问题:
- 新增合并请求体模型,自动合并两个原有模型的所有字段
- 调整
function_3直接接收合并后的请求体,再拆分传给原有两个函数处理
修改后的完整代码如下:
from fastapi import FastAPI, Depends from pydantic import BaseModel app = FastAPI() class RequestBodyChild1(BaseModel): item1: float item2: float class RequestBody1(BaseModel): parent1: RequestBodyChild1 @app.post("/function_1") def function_1(request: RequestBody1): return request class RequestBodyChild2(BaseModel): itemA: float itemB: float class RequestBody2(BaseModel): parent2: RequestBodyChild2 @app.post("/function_2") def function_2(request: RequestBody2): return request # 新增合并请求体模型,多继承自动合并两个模型的字段 class MergedRequestBody(RequestBody1, RequestBody2): pass @app.post("/function_3") def function_3(request: MergedRequestBody): # 拆分请求体传给原有两个函数处理 request_1 = function_1(RequestBody1(parent1=request.parent1)) request_2 = function_2(RequestBody2(parent2=request.parent2)) # 合并返回结果 merged_dict = request_1 | request_2 return merged_dict
修改后Swagger会自动生成你期望的合并后请求体Schema,实际运行也能正常处理同时携带parent1和parent2的请求。
可选优化方案
如果后续需要多处复用逻辑,建议不要直接把路径操作函数当依赖,抽离公共逻辑为独立依赖函数即可:
# 抽离公共业务逻辑 def handle_func1(request: RequestBody1): # 原来function_1的业务逻辑写在这里 return request def handle_func2(request: RequestBody2): # 原来function_2的业务逻辑写在这里 return request # 原有端点复用逻辑 @app.post("/function_1") def function_1(request: RequestBody1): return handle_func1(request) @app.post("/function_2") def function_2(request: RequestBody2): return handle_func2(request) @app.post("/function_3") def function_3(request: MergedRequestBody): request_1 = handle_func1(RequestBody1(parent1=request.parent1)) request_2 = handle_func2(RequestBody2(parent2=request.parent2)) return request_1 | request_2
内容的提问来源于stack exchange,提问作者Svencken
相关产品推荐
相关产品推荐

