如何定义接收任意表单输入的FastAPI端点并在OpenAPI文档中体现
实现可接收任意表单输入的FastAPI端点并同步OpenAPI文档
方法一:自定义依赖项+OpenAPI元数据注解
通过自定义依赖函数处理表单数据,同时为其添加OpenAPI元数据,让文档正确识别任意表单字段:
from fastapi import FastAPI, Request, Depends from fastapi.openapi.models import Schema, Parameter from typing import Dict, Any app = FastAPI() # 定义依赖函数,解析任意表单数据为字典 async def arbitrary_form(request: Request) -> Dict[str, Any]: return await request.form() # 为依赖项添加OpenAPI参数描述,指定为表单类型并允许任意字段 arbitrary_form.__annotations__["__openapi_param__"] = Parameter( name="arbitrary_form_data", in_="formData", schema=Schema( type="object", additionalProperties=True, example={"key1": "value1", "key2": "123", "key3": "true"} ), required=True ) @app.post("/foo") async def dofoo(form_data: Dict[str, Any] = Depends(arbitrary_form)): # 如需转换字段类型,可在此处处理(如把字符串转整数/布尔值) processed_data = {k: v for k, v in form_data.items()} return {"received_form": processed_data}
方法二:直接自定义OpenAPI文档
如果需要更灵活的文档定制,可以手动修改FastAPI生成的OpenAPI schema:
from fastapi import FastAPI, Request from fastapi.openapi.utils import get_openapi from typing import Dict, Any app = FastAPI() @app.post("/foo") async def dofoo(request: Request): form_data = await request.form() return {"received_form": dict(form_data)} # 重写OpenAPI文档生成逻辑 def custom_openapi(): if app.openapi_schema: return app.openapi_schema openapi_schema = get_openapi( title="Arbitrary Form Endpoint", version="1.0.0", description="Accepts arbitrary form data with dynamic keys", routes=app.routes, ) # 定位/foo的POST端点配置 foo_post_config = openapi_schema["paths"]["/foo"]["post"] # 添加表单请求体定义,允许任意键值对并设置示例 foo_post_config["requestBody"] = { "content": { "application/x-www-form-urlencoded": { "schema": { "type": "object", "additionalProperties": True, "example": {"username": "johndoe", "age": "30", "subscribe": "yes"} } } }, "required": True } app.openapi_schema = openapi_schema return openapi_schema app.openapi = custom_openapi
注意事项
- 表单数据默认以字符串形式传递,若需要整数、布尔值等类型,需在端点函数中自行转换处理。
- Swagger UI(FastAPI默认的文档界面)会显示示例数据,用户可以通过"Try it out"功能添加任意键值对进行测试。
- 两种方法都能让OpenAPI文档正确标识端点接受任意表单输入,方法一更偏向模块化设计,方法二更适合快速定制文档结构。
内容的提问来源于stack exchange,提问作者Petri
相关产品推荐
相关产品推荐

