FastAPI(15)- 宣告請求示例資料
阿新 • • 發佈:2022-01-05
FastAPI(15)- 宣告請求示例資料
前言
- FastAPI 可以給 Pydantic Model 或者路徑函式宣告需要接收的請求示例,而且可以顯示在 OpenAPI 文件上
- 有幾種方式,接下來會詳細介紹
Pydantic 的 schema_extra
可以使用 Config cass 和 schema_extra 為 Pydantic Model 宣告一個示例值
from typing import Optional
import uvicorn
from pydantic import BaseModel
from fastapi import FastAPI
app = FastAPI()
class Item(BaseModel):
name: str
description: Optional[str] = None
price: float
tax: Optional[float] = None
# 內部類,固定寫法
class Config:
schema_extra = {
"example": {
"name": "Foo",
"description": "A very nice Item",
"price" : 35.4,
"tax": 3.2,
}
}
@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item):
results = {"item_id": item_id, "item": item}
return results
if __name__ == "__main__":
uvicorn.run(app="13_example:app", host="127.0.0.1", port=8080, reload=True , debug=True)
檢視 Swagger API 文件
無論是 Example Value 還是 Schema 都會顯示宣告的示例值
Field 新增額外的引數
使用 Pydantic 的 Field() 時,可以將任何其他任意引數新增到函式引數中,來宣告 JSON Schema 的額外資訊
Field 的 extra 引數
預設 Field 是沒有 example 引數的,而 **extra 就是關鍵字引數,表示可以新增其他任意引數,和常見的 **kwargs 是一個作用哦
新增額外的引數: example 引數
#!usr/bin/env python
# -*- coding:utf-8 _*-
"""
# author: 小菠蘿測試筆記
# blog: https://www.cnblogs.com/poloyy/
# time: 2021/9/19 9:40 下午
# file: 12_model.py
"""
from typing import Optional
import uvicorn
from pydantic import BaseModel, Field
from fastapi import FastAPI
app = FastAPI()
class Item(BaseModel):
# 給每個欄位加上了 example 引數
name: str = Field(..., example="小菠蘿")
description: Optional[str] = Field(None, example="描述")
price: float = Field(..., example=1.11)
tax: Optional[float] = Field(None, example=3.2)
@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item):
results = {"item_id": item_id, "item": item}
return results
一定要命名為 example 嗎?
- 不一定,命名為其他也可以
- 但是隻有新增名為 example 的引數,Swagger API 上的 Example Value 才會顯示這裡傳的引數值(示例值)
重點
- 因為這裡的 example 引數是額外新增的引數,所以不會進行資料驗證
- 比如欄位型別宣告為 str,example 引數傳了陣列也不會報錯
檢視 Swagger API 文件
它是針對每個欄位設定的示例值,所以會顯示在欄位下
OpenAPI 中的 example、examples 引數
當使用 FastAPI 提供的
- Path()
- Query()
- Header()
- Cookie()
- Body()
- Form()
- File()
可以宣告一個 example 或 examples 引數,FastAPI 會自動將 example、examples 的值新增到 OpenAPI 文件中
總結
Pydantic 並沒有直接支援 example 引數,而 FastAPI 進行了擴充套件,直接支援新增 example、examples 引數
使用 Body() ,新增 example 引數
#!usr/bin/env python
# -*- coding:utf-8 _*-
"""
# author: 小菠蘿測試筆記
# blog: https://www.cnblogs.com/poloyy/
# time: 2021/9/19 9:40 下午
# file: 12_model.py
"""
from typing import Optional
import uvicorn
from pydantic import BaseModel
from fastapi import FastAPI, Body
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,
item: Item = Body(
default=...,
description="描述",
# 新增一個 example 引數
example={
"name": "body name",
"description": "body 描述",
"price": 3.33,
"tax": 5.55
},
),
):
results = {"item_id": item_id, "item": item}
return results
if __name__ == "__main__":
uvicorn.run(app="13_example:app", host="127.0.0.1", port=8080, reload=True, debug=True)
檢視 Swagger API 文件
Schema 並不會顯示 example 的值哦
使用 Body() ,新增 examples 引數
examples
本身是一個 dict,每個鍵標識一個具體的示例,而鍵對應的值也是一個 dict
每個示例 dict 可以包含
- summary:簡短描述
- description:可以包含 markdown 文字的長描述
- value:顯示的示例值
- externalValue:替代值,指向示例的 URL(不怎麼用)
實際程式碼
#!usr/bin/env python
# -*- coding:utf-8 _*-
"""
# author: 小菠蘿測試筆記
# blog: https://www.cnblogs.com/poloyy/
# time: 2021/9/19 9:40 下午
# file: 12_model.py
"""
from typing import Optional
import uvicorn
from pydantic import BaseModel, Field
from fastapi import FastAPI, Body
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,
item: Item = Body(
default=...,
# 三個鍵,代表三個不一樣的示例值
examples={
"normal": {
"summary": "正常的栗子",
"description": "A **normal** item works correctly.",
"value": {
"name": "Foo",
"description": "A very nice Item",
"price": 35.4,
"tax": 3.2,
},
},
"converted": {
"summary": "會自動轉換型別的栗子",
"description": "FastAPI can convert price `strings` to actual `numbers` automatically",
"value": {
"name": "Bar",
"price": "35.4",
},
},
"invalid": {
"summary": "校驗失敗的栗子",
"value": {
"name": "Baz",
"price": "thirty five point four",
},
},
},
),
):
results = {"item_id": item_id, "item": item}
return results
if __name__ == "__main__":
uvicorn.run(app="13_example:app", host="127.0.0.1", port=8080, reload=True, debug=True)