FastAPI教程 請求體

2021-11-02 15:01 更新

當你需要將數(shù)據(jù)從客戶端(例如瀏覽器)發(fā)送給 API 時,你將其作為「請求體」發(fā)送。

請求體是客戶端發(fā)送給 API 的數(shù)據(jù)。響應體是 API 發(fā)送給客戶端的數(shù)據(jù)。

你的 API 幾乎總是要發(fā)送響應體。但是客戶端并不總是需要發(fā)送請求體。

我們使用 Pydantic 模型來聲明請求體,并能夠獲得它們所具有的所有能力和優(yōu)點。

你不能使用 GET 操作(HTTP 方法)發(fā)送請求體。
要發(fā)送數(shù)據(jù),你必須使用下列方法之一:POST(較常見)、PUT、DELETE 或 PATCH。

導入 Pydantic 的 BaseModel

首先,你需要從 pydantic 中導入 BaseModel:

from typing import Optional

from fastapi import FastAPI
from pydantic import BaseModel


class Item(BaseModel):
    name: str
    description: Optional[str] = None
    price: float
    tax: Optional[float] = None


app = FastAPI()


@app.post("/items/")
async def create_item(item: Item):
    return item

創(chuàng)建數(shù)據(jù)模型

然后,將你的數(shù)據(jù)模型聲明為繼承自 BaseModel 的類。

使用標準的 Python 類型來聲明所有屬性:

from typing import Optional

from fastapi import FastAPI
from pydantic import BaseModel


class Item(BaseModel):
    name: str
    description: Optional[str] = None
    price: float
    tax: Optional[float] = None


app = FastAPI()


@app.post("/items/")
async def create_item(item: Item):
    return item

和聲明查詢參數(shù)時一樣,當一個模型屬性具有默認值時,它不是必需的。否則它是一個必需屬性。將默認值設為 None 可使其成為可選屬性。

例如,上面的模型聲明了一個這樣的 JSON「object」(或 Python dict):

{
    "name": "Foo",
    "description": "An optional description",
    "price": 45.2,
    "tax": 3.5
}

...由于 description 和 tax 是可選的(它們的默認值為 None),下面的 JSON「object」也將是有效的:

{
    "name": "Foo",
    "price": 45.2
}

聲明為參數(shù)

使用與聲明路徑和查詢參數(shù)的相同方式聲明請求體,即可將其添加到「路徑操作」中:

from typing import Optional

from fastapi import FastAPI
from pydantic import BaseModel


class Item(BaseModel):
    name: str
    description: Optional[str] = None
    price: float
    tax: Optional[float] = None


app = FastAPI()


@app.post("/items/")
async def create_item(item: Item):
    return item

...并且將它的類型聲明為你創(chuàng)建的 Item 模型。

結(jié)果

僅僅使用了 Python 類型聲明,F(xiàn)astAPI 將會:

  • 將請求體作為 JSON 讀取。
  • 轉(zhuǎn)換為相應的類型(在需要時)。
  • 校驗數(shù)據(jù)。如果數(shù)據(jù)無效,將返回一條清晰易讀的錯誤信息,指出不正確數(shù)據(jù)的確切位置和內(nèi)容。
  • 將接收的數(shù)據(jù)賦值到參數(shù) item 中。由于你已經(jīng)在函數(shù)中將它聲明為 Item 類型,你還將獲得對于所有屬性及其類型的一切編輯器支持(代碼補全等)。
  • 為你的模型生成 JSON 模式 定義,你還可以在其他任何對你的項目有意義的地方使用它們。
  • 這些模式將成為生成的 OpenAPI 模式的一部分,并且被自動化文檔 UI 所使用。

自動化文檔

你所定義模型的 JSON 模式將成為生成的 OpenAPI 模式的一部分,并且在交互式 API 文檔中展示:

而且還將在每一個需要它們的路徑操作的 API 文檔中使用:


編輯器支持

在你的編輯器中,你會在函數(shù)內(nèi)部的任意地方得到類型提示和代碼補全(如果你接收的是一個 dict 而不是 Pydantic 模型,則不會發(fā)生這種情況):


你還會獲得對不正確的類型操作的錯誤檢查:


這并非偶然,整個框架都是圍繞該設計而構(gòu)建。

并且在進行任何實現(xiàn)之前,已經(jīng)在設計階段經(jīng)過了全面測試,以確保它可以在所有的編輯器中生效。

Pydantic 本身甚至也進行了一些更改以支持此功能。

上面的截圖取自 Visual Studio Code。

但是在 PyCharm 和絕大多數(shù)其他 Python 編輯器中你也會獲得同樣的編輯器支持:


使用模型

在函數(shù)內(nèi)部,你可以直接訪問模型對象的所有屬性:

from typing import Optional

from fastapi import FastAPI
from pydantic import BaseModel


class Item(BaseModel):
    name: str
    description: Optional[str] = None
    price: float
    tax: Optional[float] = None


app = FastAPI()


@app.post("/items/")
async def create_item(item: Item):
    item_dict = item.dict()
    if item.tax:
        price_with_tax = item.price + item.tax
        item_dict.update({"price_with_tax": price_with_tax})
    return item_dict

請求體 + 路徑參數(shù)

你可以同時聲明路徑參數(shù)和請求體。

FastAPI 將識別出與路徑參數(shù)匹配的函數(shù)參數(shù)應從路徑中獲取,而聲明為 Pydantic 模型的函數(shù)參數(shù)應從請求體中獲取。

from typing import Optional

from fastapi import FastAPI
from pydantic import BaseModel


class Item(BaseModel):
    name: str
    description: Optional[str] = None
    price: float
    tax: Optional[float] = None


app = FastAPI()


@app.put("/items/{item_id}")
async def create_item(item_id: int, item: Item):
    return {"item_id": item_id, **item.dict()}

請求體 + 路徑參數(shù) + 查詢參數(shù)

你還可以同時聲明請求體、路徑參數(shù)和查詢參數(shù)。

FastAPI 會識別它們中的每一個,并從正確的位置獲取數(shù)據(jù)。

from typing import Optional

from fastapi import FastAPI
from pydantic import BaseModel


class Item(BaseModel):
    name: str
    description: Optional[str] = None
    price: float
    tax: Optional[float] = None


app = FastAPI()


@app.put("/items/{item_id}")
async def create_item(item_id: int, item: Item, q: Optional[str] = None):
    result = {"item_id": item_id, **item.dict()}
    if q:
        result.update({"q": q})
    return result

函數(shù)參數(shù)將依次按如下規(guī)則進行識別:

  • 如果在路徑中也聲明了該參數(shù),它將被用作路徑參數(shù)。
  • 如果參數(shù)屬于單一類型(比如 int、float、str、bool 等)它將被解釋為查詢參數(shù)。
  • 如果參數(shù)的類型被聲明為一個 Pydantic 模型,它將被解釋為請求體。

不使用 Pydantic

如果你不想使用 Pydantic 模型,你還可以使用 Body 參數(shù)。請參閱文檔 請求體 - 多個參數(shù):請求體中的單一值。


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

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號