當你需要將數(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:
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ù)據(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ù)的相同方式聲明請求體,即可將其添加到「路徑操作」中:
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 模型。
僅僅使用了 Python 類型聲明,F(xiàn)astAPI 將會:
你所定義模型的 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ù)和請求體。
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ù)。
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ī)則進行識別:
如果你不想使用 Pydantic 模型,你還可以使用 Body 參數(shù)。請參閱文檔 請求體 - 多個參數(shù):請求體中的單一值。
更多建議: