FastAPI(8)- 請求體 Request Body


前言

  • 接口傳參方式之一:通過發送請求體(Request Body)來傳遞請求數據
  • 在 FastAPI,提倡使用 Pydantic 模型來定義請求體
  • 這篇文章會詳細講不使用 Pydantic 和 使用 Pydantic 發送請求體的栗子

 

注意

  • 請求體並不是只有 POST 請求有,只不過 POST 更常見
  • 在 PUT、DELETE、PATCH 請求中都可以使用請求體
  • 其實,在 GET 請求中也可以用請求體,不過僅適用於非常極端的情況下,而且 Swagger API 並不會顯示 GET 請求的請求體

 

不使用 Pydantic的栗子

from fastapi import FastAPI
import uvicorn

app = FastAPI()


@app.post("/items")
async def read_item(item: dict):
    return {"item": item}


if __name__ == "__main__":
    uvicorn.run(app="6_request:app", host="127.0.0.1", port=8080, reload=True, debug=True)

指定查詢參數的類型為 dict

 

正確傳參的請求結果

 

查看請求頭

是 json 格式,符合預期 

 

重點

  • 用 postman 發起請求的話,一定要選 JSON 格式哦
  • 因為接收的是 dict,所以 FastAPI 會自動將 JSON 字符串轉換為 dict
  • 這種場景下,雖然查詢參數叫 item,但請求體的字段名可以隨意取,字段數量也可以任意個

 

錯誤傳參的請求結果

選了 text 之后,因為不是 JSON 字符串,FastAPI 無法正確解析請求體為 dict,所以會報類型錯誤的提示

 

查看請求頭

 

類型是 text

 

用 Dict 代替 dict 的栗子

Dict 是 typing 模塊提供的類,可以指定鍵值對的數據類型

from typing import Dict

from fastapi import FastAPI

app = FastAPI()


@app.post("/Dict/")
# 鍵為 str,值為 float
async def create_index_weights(weights: Dict[str, float]):
    return weights

 

使用 Dict 相比直接用 dict 的好處

聲明為 Dict[str, float],FastAPI 會對每一個鍵值對都做數據校驗,校驗失敗會有友好的錯誤提示

 

正確傳參的請求結果

 

校驗失敗的請求結果

友好的錯誤提示啊~

 

使用 Pydantic 模型(建議使用)

實際栗子

from fastapi import FastAPI
from typing import Optional
from pydantic import BaseModel

app = FastAPI()


# 自定義一個 Pydantic 模型
class Item(BaseModel):
    name: str
    description: Optional[str] = None
    price: float
    tax: Optional[float] = None


@app.post("/items/")
# item 參數的類型指定為 Item 模型
async def create_item(item: Item): 
    return item

 

參數指定為 Pydantic 模型后,FastAPI 做了這幾件事

  1. 將請求體識別為 JSON 字符串
  2. 將字段值轉換相應的類型(若有需要)
  3. 驗證數據,如果驗證失敗,會返回一個清晰的錯誤,准確指出錯誤數據的位置和信息
  4. item 會接收到完整的請求體數據,擁有所有屬性及其類型,IDE 也會給予對應的智能提示
  5. 給 Pydantic 模型自動的生成 JSON Schema,這些 Schema 會成為生成 OpenAPI Schema 的一部分,並顯示在接口文檔上

 

正確傳參的請求結果

正常傳參,所有屬性按指定的類型進行傳數據

 

字段值類型自動轉換

  •  name: str  傳了 bool 類型的數據
  •  description: str  傳了 float 類型的數據
  •  price: float   傳了 int 類型的數據
  •  tax: float  傳了 bool 類型的數據

FastAPi 會將傳進來的值自動轉換為指定類型的值

  • 將 true 轉成 str 類型,即 "True"
  • 將 12.22 轉成 str 類型,即 "12.22"
  • 將 12 轉成 float 類型,即 12.0
  • 將 true 轉成 float 類型,即 1.0

如果轉換失敗,則會報 type_error 錯誤(如下圖)

 

驗證數據失敗的請求結果

 

查看 Swagger API 文檔

Schema 部分

model 的 JSON Schema 會成為 Swagger APi 文檔的一部分

 

示例值部分

 

IDE 智能提示

因為知道 name 屬性的類型是 str,所以 IDE 會智能提示 str 內置的方法

 

Request body + path + query parameters 綜合栗子

  • 可以同時聲明請求體、路徑參數、查詢參數
  • FastAPI 可以識別出它們中的每一個,並從正確的位置獲取到數據

 

實際代碼

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,
        # 查詢參數
        name: Optional[str] = None):
    result = {"item_id": item_id, **item.dict()}
    print(result)
    if name:
        # 如果查詢參數 name 不為空,則替換掉 item 參數里面的 name 屬性值
        result.update({"name": name})
    return result

 

FastAPI 識別參數的邏輯

  • 如果參數也在路徑中聲明,它將解釋為路徑參數【item_id】
  • 如果參數是單數類型(如int、float、str、boo l等),它將被解釋為查詢參數【name】
  • 如果參數被聲明為 Pydantic 模型的類型,它將被解析為請求體【item】

 

正確傳參的請求結果

 

Pycharm Console 輸出結果

打印 result 的值

{'item_id': 1234, 'name': '小菠蘿', 'description': '描述,非必填', 'price': 12.22, 'tax': 0.0}

 

查看 Swagger API 文檔

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM