FastAPI(10)- 詳解 Body
阿新 • • 發佈:2022-01-05
FastAPI(10)- 詳解 Body
前言
- 上一篇有講到將引數型別指定為 Pydantic Model,這樣 FastAPI 會解析它為一個 Request Body
- 那單型別(int、float、str、bool...)引數可以成為 Request Body 的一部分嗎?答案是可以的
- 通過 Body 函式即可完成,和 Path、Query 有異曲同工之妙
文章跳轉
Body
- 主要作用:可以將單型別的引數成為 Request Body 的一部分,即從查詢引數變成請求體引數
- 和 Query、Path 提供的額外校驗、元資料是基本一致的(多了個 embed 引數,最後講解)
Body 的簡單栗子
from typing import Optional
import uvicorn
from fastapi import Body, FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: Optional[str] = None
price: float
tax: Optional[float] = None
class User(BaseModel):
username: str
full_name: Optional[str] = None
@app.put("/items/{item_id}")
async def update_item(
item_id: int,
item: Item,
user: User,
importance: int = Body(...)
):
results = {"item_id": item_id, "item": item, "user": user, "importance": importance}
return results
if __name__ == "__main__":
uvicorn.run(app="8_Body:app", host="127.0.0.1", port=8080, reload=True, debug=True)
期望得到的 Request Body
{
"item": {
"name": "Foo",
"description": "The pretender",
"price": 42.0,
"tax": 3.2
},
"user": {
"username": "dave",
"full_name": "Dave Grohl"
},
"importance": 5
}
Request Body 中多了個 importance
正確傳參的請求結果
檢視 Swagger API 文件
Query、Path、Body 終極混用
from typing import Optional
import uvicorn
from fastapi import Body, FastAPI, Path, Query
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: Optional[str] = None
price: float
tax: Optional[float] = None
class User(BaseModel):
username: str
full_name: Optional[str] = None
@app.put("/item_all/{item_id}")
async def update_item(
*,
item_id: int = Path(default=..., description="路徑引數", gt=0, lt=10),
address: str = Query(default=None, description="查詢引數", max_length=10),
item: Item,
user: User,
importance: int = Body(default=..., description="請求體", ge=1, le=5)
):
results = {
"item_id": item_id,
"address": address,
"item": item,
"user": user,
"importance": importance
}
return results
正確傳參的請求結果
檢視 Swagger API 文件
Body() 中的 embed 引數
為什麼要講這個 embed 引數
當函式只有一個引數指定了 Pydantic Model 且沒有其他 Body 引數時,傳參的時候請求體可以不指定引數名
class Item(BaseModel):
name: str
description: Optional[str] = None
price: float
tax: Optional[float] = None
@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item):
...
期望得到的請求體
{
"name": "Foo",
"description": "The pretender",
"price": 42.0,
"tax": 3.2
}
預設並不需要指定 item 為欄位名
那假設想指定 item 為請求體的欄位名呢?就是通過 embed 引數達到目的了
實際程式碼
from typing import Optional
from fastapi import Body, FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: Optional[str] = None
price: float
tax: Optional[float] = None
@app.put("/items/{item_id}")
async def update_item(
*,
item_id: int,
# 將 embed 設定為 True
item: Item = Body(..., embed=True)):
results = {"item_id": item_id, "item": item}
return results
期望得到的請求體
{
"item": {
"name": "Foo",
"description": "The pretender",
"price": 42.0,
"tax": 3.2
}
}