【问题标题】:How to create an OpenAPI schema for an UploadFile in FastAPI?如何在 FastAPI 中为 UploadFile 创建 OpenAPI 模式?
【发布时间】:2020-03-19 21:30:05
【问题描述】:

FastAPI 自动为 UploadFile 参数生成 OpenAPI 规范中的架构。

例如这段代码:

from fastapi import FastAPI, File, UploadFile

app = FastAPI()


@app.post("/uploadfile/")
async def create_upload_file(file: UploadFile = File(..., description="The file")):
    return {"filename": file.filename}

将在 OpenAPI 规范中的 components:schemas 下生成此架构:

{
    "Body_create_upload_file_uploadfile__post": {
        "title": "Body_create_upload_file_uploadfile__post",
        "required":["file"],
        "type":"object",
        "properties":{
            "file": {"title": "File", "type": "string", "description": "The file","format":"binary"}
        }
    }
}

如何明确指定 UploadFiles 的架构(或至少是其名称)?

我已阅读 FastAPIs 文档并搜索了问题跟踪器,但一无所获。

【问题讨论】:

标签: python openapi fastapi


【解决方案1】:

我在FastAPI#1442 上回答了这个问题,但以防万一其他人偶然发现这个问题,这里复制粘贴了上面链接的帖子:

经过一番调查,这是可能的,但它需要一些猴子补丁。使用here 给出的示例,解决方案如下所示:

from fastapi import FastAPI, File, UploadFile
from typing import Callable

app = FastAPI()

@app.post("/files/")
async def create_file(file: bytes = File(...)):
    return {"file_size": len(file)}

@app.post("/uploadfile/")
async def create_upload_file(file: UploadFile = File(...)):
    return {"filename": file.filename}

def update_schema_name(app: FastAPI, function: Callable, name: str) -> None:
    """
    Updates the Pydantic schema name for a FastAPI function that takes
    in a fastapi.UploadFile = File(...) or bytes = File(...).

    This is a known issue that was reported on FastAPI#1442 in which
    the schema for file upload routes were auto-generated with no
    customization options. This renames the auto-generated schema to
    something more useful and clear.

    Args:
        app: The FastAPI application to modify.
        function: The function object to modify.
        name: The new name of the schema.
    """
    for route in app.routes:
        if route.endpoint is function:
            route.body_field.type_.__name__ = name
            break

update_schema_name(app, create_file, "CreateFileSchema")
update_schema_name(app, create_upload_file, "CreateUploadSchema")

【讨论】:

    【解决方案2】:

    您可以编辑 OpenAPI 架构本身。我更喜欢将这些模式移动到路径中(因为它们对于每条路径都是唯一的):

    from fastapi import FastAPI, File, UploadFile
    from fastapi.openapi.utils import get_openapi
    
    
    app = FastAPI()
    
    
    @app.post("/uploadfile/")
    async def create_upload_file(file1: UploadFile = File(...), file2: UploadFile = File(...)):
        pass
    
    
    def custom_openapi():
        if app.openapi_schema:
            return app.openapi_schema
        openapi_schema = get_openapi(
            title="Custom title",
            version="2.5.0",
            description="This is a very custom OpenAPI schema",
            routes=app.routes,
        )
        # Move autogenerated Body_ schemas, see https://github.com/tiangolo/fastapi/issues/1442
        for path in openapi_schema["paths"].values():
            for method_data in path.values():
                if "requestBody" in method_data:
                    for content_type, content in method_data["requestBody"]["content"].items():
                        if content_type == "multipart/form-data":
                            schema_name = content["schema"]["$ref"].lstrip("#/components/schemas/")
                            schema_data = openapi_schema["components"]["schemas"].pop(schema_name)
                            content["schema"] = schema_data
        app.openapi_schema = openapi_schema
        return app.openapi_schema
    
    app.openapi = custom_openapi
    

    【讨论】:

      猜你喜欢
      • 2020-12-14
      • 1970-01-01
      • 2021-03-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-06-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多