有没有办法在 FastAPI/OpenAPI 中拥有多个响应模型?

Dha*_*lia 17 openapi pydantic fastapi

我正在编写一个应用程序,我需要根据逻辑有两组完全不同的响应结构。

有什么方法可以处理这个问题,以便我可以序列化、验证和返回两个不同的响应模型并反映在 OpenAPI JSON 中?

我正在使用 pydantic 来编写模型。

Dje*_*eth 14

是的,这是可能的。您可以在路径装饰器的参数中使用 Union response_model=(我使用下面的新 python 3.10 样式)。这是一个完整的示例,这将按原样工作。

\n
from typing import Union\n\nfrom fastapi import FastAPI, Query\nfrom pydantic import BaseModel\n\nclass responseA(BaseModel):\n    name: str\n\nclass responseB(BaseModel):\n    id: int\n\napp = FastAPI()\n\n@app.get("/", response_model=Union[responseA,responseB])\ndef base(q: int|str = Query(None)):\n    if q and isinstance(q, str):\n        return responseA(name=q)\n    if q and isinstance(q, int):\n        return responseB(id=q)\n    raise HTTPException(status_code=400, detail="No q param provided")\n\nif __name__ == "__main__":\n    import uvicorn\n    uvicorn.run(app, host="0.0.0.0", port=8000,  )\n
Run Code Online (Sandbox Code Playgroud)\n

编辑:正如 Tom\xc3\xa1\xc5\xa1Linhart 在下面的评论中指出的,参数response_model必须使用Union. 在最初的答案中,我使用了 3.10 样式responseA|responseB,但它并不适合所有人,如文档中所述。
\n文档中的结果:\n在此输入图像描述

\n

  • 以前的 python 版本的替代方案可以是 `@app.get("/", response_model=Union[responseA, responseB])` (4认同)

Dr.*_*r.X 5

如果您需要响应多个示例,您可以尝试以下操作:

@router.get(
    '/{UserId}',
    summary='get user',
    responses={
        200: {
            "description": "",
            "content": {
                "application/json": {
                    "examples": {
                        "Corporate user": {
                            'value': {
                                'foo': 'bar',
                            },
                        },
                        "Standard user": {
                            'value': {
                                'doo': 'www',
                            },
                        },
                    }
                }
            }
        }
    }
)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述