FastAPI教程 OpenAPI 中的其他響應(yīng)

2021-11-08 09:50 更新

警告

這是一個(gè)比較高級(jí)的話題。

如果您從FastAPI開始,您可能不需要這個(gè)。

您可以聲明額外的響應(yīng),包括額外的狀態(tài)代碼、媒體類型、描述等。

這些額外的響應(yīng)將包含在 OpenAPI 架構(gòu)中,因此它們也會(huì)出現(xiàn)在 API 文檔中。

但是,對(duì)于那些你必須確保其他答復(fù)你返回一個(gè)Response喜歡JSONResponse直接,你的狀態(tài)代碼和內(nèi)容。

附加響應(yīng) model

您可以將參數(shù)傳遞給路徑操作裝飾器responses。

它接收 a dict,鍵是每個(gè)響應(yīng)的狀態(tài)代碼,例如200,值是 other ,其中包含每個(gè)響應(yīng)dict的信息。

每個(gè)響應(yīng)dict都可以有一個(gè) key model,包含一個(gè) Pydantic 模型,就像response_model.

FastAPI將采用該模型,生成其 JSON 模式并將其包含在 OpenAPI 中的正確位置。

例如,要使用狀態(tài)代碼404和 Pydantic 模型聲明另一個(gè)響應(yīng)Message,您可以編寫:

from fastapi import FastAPI
from fastapi.responses import JSONResponse
from pydantic import BaseModel


class Item(BaseModel):
    id: str
    value: str


class Message(BaseModel):
    message: str


app = FastAPI()


@app.get("/items/{item_id}", response_model=Item, responses={404: {"model": Message}})
async def read_item(item_id: str):
    if item_id == "foo":
        return {"id": "foo", "value": "there goes my hero"}
    else:
        return JSONResponse(status_code=404, content={"message": "Item not found"})

筆記

請(qǐng)記住,您必須JSONResponse直接返回。

信息

的model關(guān)鍵不是的OpenAPI的一部分。

FastAPI將從那里獲取 Pydantic 模型,生成JSON Schema,并將其放在正確的位置。

正確的地方是:

  • 在 key 中content,它具有另一個(gè) JSON 對(duì)象 ( dict)作為值,其中包含:具有媒體類型的鍵,例如application/json,包含另一個(gè) JSON 對(duì)象作為值,其中包含:一個(gè) key schema,它具有模型中的 JSON Schema 的值,這是正確的位置。FastAPI在此處添加對(duì)OpenAPI中另一個(gè)位置的全局 JSON 模式的引用,而不是直接包含它。這樣,其他應(yīng)用程序和客戶端可以直接使用那些 JSON Schemas,提供更好的代碼生成工具等。

在 OpenAPI 中為此路徑操作生成的響應(yīng)將是:

{
    "responses": {
        "404": {
            "description": "Additional Response",
            "content": {
                "application/json": {
                    "schema": {
                        "$ref": "#/components/schemas/Message"
                    }
                }
            }
        },
        "200": {
            "description": "Successful Response",
            "content": {
                "application/json": {
                    "schema": {
                        "$ref": "#/components/schemas/Item"
                    }
                }
            }
        },
        "422": {
            "description": "Validation Error",
            "content": {
                "application/json": {
                    "schema": {
                        "$ref": "#/components/schemas/HTTPValidationError"
                    }
                }
            }
        }
    }
}

這些模式被引用到 OpenAPI 模式中的另一個(gè)地方:

{
    "components": {
        "schemas": {
            "Message": {
                "title": "Message",
                "required": [
                    "message"
                ],
                "type": "object",
                "properties": {
                    "message": {
                        "title": "Message",
                        "type": "string"
                    }
                }
            },
            "Item": {
                "title": "Item",
                "required": [
                    "id",
                    "value"
                ],
                "type": "object",
                "properties": {
                    "id": {
                        "title": "Id",
                        "type": "string"
                    },
                    "value": {
                        "title": "Value",
                        "type": "string"
                    }
                }
            },
            "ValidationError": {
                "title": "ValidationError",
                "required": [
                    "loc",
                    "msg",
                    "type"
                ],
                "type": "object",
                "properties": {
                    "loc": {
                        "title": "Location",
                        "type": "array",
                        "items": {
                            "type": "string"
                        }
                    },
                    "msg": {
                        "title": "Message",
                        "type": "string"
                    },
                    "type": {
                        "title": "Error Type",
                        "type": "string"
                    }
                }
            },
            "HTTPValidationError": {
                "title": "HTTPValidationError",
                "type": "object",
                "properties": {
                    "detail": {
                        "title": "Detail",
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/ValidationError"
                        }
                    }
                }
            }
        }
    }
}

主要響應(yīng)的其他媒體類型

您可以使用相同的responses參數(shù)為相同的主響應(yīng)添加不同的媒體類型。

例如,您可以添加額外的媒體類型image/png,聲明您的路徑操作可以返回 JSON 對(duì)象(具有媒體類型application/json)或 PNG 圖像:

from typing import Optional

from fastapi import FastAPI
from fastapi.responses import FileResponse
from pydantic import BaseModel


class Item(BaseModel):
    id: str
    value: str


app = FastAPI()


@app.get(
    "/items/{item_id}",
    response_model=Item,
    responses={
        200: {
            "content": {"image/png": {}},
            "description": "Return the JSON item or an image.",
        }
    },
)
async def read_item(item_id: str, img: Optional[bool] = None):
    if img:
        return FileResponse("image.png", media_type="image/png")
    else:
        return {"id": "foo", "value": "there goes my hero"}

筆記

請(qǐng)注意,您必須FileResponse直接使用 a 返回圖像。

信息

除非您在responses參數(shù)中明確指定不同的媒體類型,否則 FastAPI 將假定響應(yīng)具有與主響應(yīng)類相同的媒體類型(默認(rèn)application/json)。

但是,如果您指定了一個(gè)自定義響應(yīng)類None作為其媒體類型,F(xiàn)astAPI 將application/json用于具有關(guān)聯(lián)模型的任何其他響應(yīng)。

組合信息

您也可以從多個(gè)地方,包括結(jié)合響應(yīng)信息response_model,status_code以及responses參數(shù)。

您可以聲明response_model, 使用默認(rèn)狀態(tài)代碼200(或自定義狀態(tài)代碼,如果需要),然后responses直接在 OpenAPI 架構(gòu)中聲明相同響應(yīng)的其他信息。

FastAPI將保留來自 的附加信息responses,并將其與模型中的 JSON 模式結(jié)合起來。

例如,您可以404使用使用 Pydantic 模型并具有自定義description.

以及帶有200使用您的狀態(tài)代碼的響應(yīng)response_model,但包括自定義example:

from fastapi import FastAPI
from fastapi.responses import JSONResponse
from pydantic import BaseModel


class Item(BaseModel):
    id: str
    value: str


class Message(BaseModel):
    message: str


app = FastAPI()


@app.get(
    "/items/{item_id}",
    response_model=Item,
    responses={
        404: {"model": Message, "description": "The item was not found"},
        200: {
            "description": "Item requested by ID",
            "content": {
                "application/json": {
                    "example": {"id": "bar", "value": "The bar tenders"}
                }
            },
        },
    },
)
async def read_item(item_id: str):
    if item_id == "foo":
        return {"id": "foo", "value": "there goes my hero"}
    else:
        return JSONResponse(status_code=404, content={"message": "Item not found"})

它將全部組合并包含在您的 OpenAPI 中,并顯示在 API 文檔中:

結(jié)合預(yù)定義響應(yīng)和自定義響應(yīng)

您可能希望有一些適用于許多路徑操作的預(yù)定義響應(yīng),但您希望將它們與每個(gè)路徑操作所需的自定義響應(yīng)結(jié)合起來。

對(duì)于這些情況,您可以使用“解包”一個(gè)的Python的技術(shù)dict有**dict_to_unpack:

old_dict = {
    "old key": "old value",
    "second old key": "second old value",
}
new_dict = {**old_dict, "new key": "new value"}

在這里,new_dict將包含來自old_dict加上新的鍵值對(duì)的所有鍵值對(duì):

{
    "old key": "old value",
    "second old key": "second old value",
    "new key": "new value",
}

您可以使用該技術(shù)在路徑操作中重用一些預(yù)定義的響應(yīng),并將它們與其他自定義響應(yīng)結(jié)合起來。

例如:

from typing import Optional

from fastapi import FastAPI
from fastapi.responses import FileResponse
from pydantic import BaseModel


class Item(BaseModel):
    id: str
    value: str


responses = {
    404: {"description": "Item not found"},
    302: {"description": "The item was moved"},
    403: {"description": "Not enough privileges"},
}


app = FastAPI()


@app.get(
    "/items/{item_id}",
    response_model=Item,
    responses={**responses, 200: {"content": {"image/png": {}}}},
)
async def read_item(item_id: str, img: Optional[bool] = None):
    if img:
        return FileResponse("image.png", media_type="image/png")
    else:
        return {"id": "foo", "value": "there goes my hero"}

有關(guān) OpenAPI 響應(yīng)的更多信息

要查看您可以在響應(yīng)中包含的內(nèi)容,您可以查看 OpenAPI 規(guī)范中的以下部分:

  • OpenAPI 響應(yīng)對(duì)象,它包括Response Object.
  • OpenAPI Response Object,您可以直接在responses參數(shù)中的每個(gè)響應(yīng)中包含任何內(nèi)容。包括description, headers, content(這里面就是你聲明了不同的媒體類型和 JSON Schemas), 和links.


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)