如何在FastAPI的Pydantic模型中使用openapi_examples实现Swagger多示例
在Pydantic模型中实现SwaggerUI请求体下拉示例菜单
你遇到的问题是:想通过Pydantic类定义请求体的多示例,让SwaggerUI显示下拉选择菜单,但将openapi_examples放在Pydantic的json_schema_extra里不生效,而examples仅能显示平铺的示例而非下拉菜单。
问题原因
openapi_examples是FastAPI路由装饰器(如@app.post)的专属参数,并非Pydantic模型json_schema_extra的有效配置项,因此你在CreateRequest2中的写法不会被FastAPI识别,自然无法在SwaggerUI生成下拉菜单。而json_schema_extra里的examples属于JSON Schema标准字段,SwaggerUI只会将其渲染为平铺的多示例,而非下拉选择形式。
解决方案
要实现下拉式多示例菜单,有两种实用方案:
方式一:在路由装饰器中直接配置openapi_examples
这是官方推荐的方式,路由层面同样支持该参数,可直接生成下拉菜单:
from fastapi import FastAPI from fastapi.openapi.models import Example from pydantic import BaseModel, Field app = FastAPI() class CreateRequest2(BaseModel): name: str = Field(..., description="Name of the created item") value: str = Field(..., description="Value of the created item") # 在路由中配置多示例,生成下拉菜单 @app.post("/2", openapi_examples={ "普通物品": Example( summary="常规示例", description="创建一个普通名称的物品", value={"name": "Item1", "value": "Value1"} ), "特殊物品": Example( summary="特殊标识示例", description="创建一个带特殊前缀的物品", value={"name": "Special_Item", "value": "Special_Value"} ) } ) def create_item2(body: CreateRequest2): return {"name": body.name}
方式二:从Pydantic模型提取示例,自定义OpenAPI规范
若想将示例定义在模型内部以避免路由代码冗余,可通过自定义OpenAPI生成函数,将模型内预定义的示例注入到OpenAPI规范中:
from fastapi import FastAPI from fastapi.openapi.models import Example from pydantic import BaseModel, ConfigDict, Field from fastapi.openapi.utils import get_openapi app = FastAPI() class CreateRequest2(BaseModel): name: str = Field(..., description="Name of the created item") value: str = Field(..., description="Value of the created item") # 在模型内部定义自定义示例集合 model_config = ConfigDict( json_schema_extra={ "custom_examples": { "普通物品": Example( summary="常规示例", description="创建一个普通名称的物品", value={"name": "Item1", "value": "Value1"} ), "特殊物品": Example( summary="特殊标识示例", description="创建一个带特殊前缀的物品", value={"name": "Special_Item", "value": "Special_Value"} ) } } ) @app.post("/2") def create_item2(body: CreateRequest2): return {"name": body.name} # 自定义OpenAPI生成逻辑,注入模型示例 def custom_openapi(): if app.openapi_schema: return app.openapi_schema openapi_schema = get_openapi( title="Custom API", version="1.0.0", description="从Pydantic模型提取示例的API", routes=app.routes, ) # 遍历路由,将模型示例注入到请求体配置中 for path in openapi_schema["paths"].values(): for method in path.values(): if "requestBody" in method and "application/json" in method["requestBody"]["content"]: content = method["requestBody"]["content"]["application/json"] schema_ref = content["schema"].get("$ref") if schema_ref: model_name = schema_ref.split("/")[-1] target_model = next((m for m in [CreateRequest2] if m.__name__ == model_name), None) if target_model and "custom_examples" in target_model.model_config.get("json_schema_extra", {}): content["examples"] = target_model.model_config["json_schema_extra"]["custom_examples"] app.openapi_schema = openapi_schema return app.openapi_schema app.openapi = custom_openapi
效果说明
- 方式一:直接在路由配置
openapi_examples,SwaggerUI会自动生成下拉菜单,每个示例包含独立名称、描述和值,用户可一键切换。 - 方式二:示例集中定义在Pydantic模型内部,通过统一逻辑注入到OpenAPI规范,适合多路由复用同一模型示例的场景。
内容的提问来源于stack exchange,提问作者bueny
相关产品推荐
相关产品推荐

