在實作中會遇到需要將資料發送到Server的情境,比如新增使用者、更新帳號密碼等等。
這些時候會使用 Post、Put、Patch 等可以帶資料的 http method,這個時候便可以在 request body 中夾帶需要傳送的資料,資料的格式可以根據情境來制定,通常最常使用的是 JSON 的格式。
在 FastAPI 中,我們使用 Pydantic 進行資料格式的制定與驗證。
從 Python 3.5 之後引入了 type hints 功能,可以在程式碼中對變數做型別的提示,可以讓 IDE 或分析工具幫助我們偵測型別的錯誤。
Pydantic 基於 type hints 的基礎上,建立了可以進行資料驗證的類別模型,我們只需要引用其模型並進行定義,便可為我們的資料進行型別驗證。
from pydantic import BaseModel
class Order(BaseModel):
id: int
user_id: int
detail: str
在上面的例子中,我們透過繼承 BaseModel 來定義一個 pydantic 的模型 Order,裡面定義了 id、user_id 必須要為整數,detail 必須為字串。
new_order = Order(
id = 1,
user_id = 2,
detail = 'egg'
)
在使用時只需要使用需要的資料實體化,便會幫我們進行型別的驗證。
new_order = Order(
id = 'string',
user_id = 2,
detail = 'egg'
)
若是輸入錯誤型別的資料,便會引發驗證錯誤:
---------------------------------------------------------------------------
ValidationError Traceback (most recent call last)
Cell In[5], line 1
----> 1 new_order = Order(
2 id = "string",
3 user_id = 2,
4 detail = 'egg'
5 )
File d:\workspace\python\venv\Fast\lib\site-packages\pydantic\main.py:342, in pydantic.main.BaseModel.__init__()
ValidationError: 1 validation error for Order
id
value is not a valid integer (type=type_error.integer)
在 FastAPI 中可以使用 Pydantic model 對傳入API的資料進行驗證,我們可以建立一個範例接口來進行測試。
class OrderCreateInput(BaseModel):
user_id: int
detail: str
@app.post("/orders", status_code=status.HTTP_201_CREATED)
def create_order(data: OrderCreateInput):
return 'created'
我們新增一個新增訂單的接口與 Pydantic model,在接口對應的方法中將輸入的 data 聲名為一個 OrderCreateInput 物件,使用者在使用這個接口時便需要傳入對應的 JSON 格式資料。
在API文件中可以看到該接口的 Request body 需要傳入我們定義好的格式資料。
若是輸入錯誤的資料便會返回 422 錯誤,告訴使用者資料格式哪裡有問題。
class OrderUpdateInput(BaseModel):
detail: str
@app.put("/orders/{id}")
def update_order(id: int, data: OrderUpdateInput):
return {"id": id, "detail": data.detail}
你可以同時使用 Request body、路徑參數和查詢參數來傳遞資料,記得使用不同的變數命名進行區分,若變數名稱相同時被解析的優先順序為:
路徑參數>查詢參數>Request body
from pydantic import BaseModel, Field
class OrderUpdateInput(BaseModel):
detail: str | None = Field(
default=None, min_length=5, max_length=50, title="Order detail"
)
可以使用 Field 來對資料驗證更多內容,例如最小長度、最大長度等等。
透過 Pydantic 的 model 我們可以驗證輸入輸出的資料型別、以及決定要使用哪些資料,這也會大幅增加開發上的便利性及安全性。型別只要定義好,那我們就可以保證輸入的資料是我們想要的了。
Welcome to Pydantic - Pydantic