您好,登錄后才能下訂單哦!
本篇內容介紹了“如何使用參數聲明FastAPI響應模型”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
你可以在任意的路徑操作中使用 response_model 參數來聲明用于響應的模型:
@app.get()
@app.post()
@app.put()
@app.delete()
等等。
from typing import List, Optional
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: Optional[str] = None
price: float
tax: Optional[float] = None
tags: List[str] = []
@app.post("/items/", response_model=Item)
async def create_item(item: Item):
return item
Note
注意,response_model是「裝飾器」方法(get,post 等)的一個參數。不像之前的所有參數和請求體,它不屬于路徑操作函數。
它接收的類型與你將為 Pydantic 模型屬性所聲明的類型相同,因此它可以是一個 Pydantic 模型,但也可以是一個由 Pydantic 模型組成的 list,例如 List[Item]。
FastAPI 將使用此 response_model 來:
將輸出數據轉換為其聲明的類型。
校驗數據。
在 OpenAPI 的路徑操作中為響應添加一個 JSON Schema。
并在自動生成文檔系統中使用。
但最重要的是:
會將輸出數據限制在該模型定義內。下面我們會看到這一點有多重要。
技術細節
響應模型在參數中被聲明,而不是作為函數返回類型的注解,這是因為路徑函數可能不會真正返回該響應模型,而是返回一個 dict、數據庫對象或其他模型,然后再使用 response_model 來執行字段約束和序列化。
1、返回與輸入相同的數據
現在我們聲明一個 UserIn 模型,它將包含一個明文密碼屬性。
from typing import Optional
from fastapi import FastAPI
from pydantic import BaseModel, EmailStr
app = FastAPI()
class UserIn(BaseModel):
username: str
password: str
email: EmailStr
full_name: Optional[str] = None
# Don't do this in production!
@app.post("/user/", response_model=UserIn)
async def create_user(user: UserIn):
return user
我們正在使用此模型聲明輸入數據,并使用同一模型聲明輸出數據:
from typing import Optional
from fastapi import FastAPI
from pydantic import BaseModel, EmailStr
app = FastAPI()
class UserIn(BaseModel):
username: str
password: str
email: EmailStr
full_name: Optional[str] = None
# Don't do this in production!
@app.post("/user/", response_model=UserIn)
async def create_user(user: UserIn):
return user
現在,每當瀏覽器使用一個密碼創建用戶時,API 都會在響應中返回相同的密碼。
在這個案例中,這可能不算是問題,因為用戶自己正在發送密碼。
但是,如果我們在其他的路徑操作中使用相同的模型,則可能會將用戶的密碼發送給每個客戶端。
Danger
永遠不要存儲用戶的明文密碼,也不要在響應中發送密碼。
3、添加輸出模型
相反,我們可以創建一個有明文密碼的輸入模型和一個沒有明文密碼的輸出模型:
from typing import Optional
from fastapi import FastAPI
from pydantic import BaseModel, EmailStr
app = FastAPI()
class UserIn(BaseModel):
username: str
password: str
email: EmailStr
full_name: Optional[str] = None
class UserOut(BaseModel):
username: str
email: EmailStr
full_name: Optional[str] = None
@app.post("/user/", response_model=UserOut)
async def create_user(user: UserIn):
return user
這樣,即便我們的路徑操作函數將會返回包含密碼的相同輸入用戶:
from typing import Optional
from fastapi import FastAPI
from pydantic import BaseModel, EmailStr
app = FastAPI()
class UserIn(BaseModel):
username: str
password: str
email: EmailStr
full_name: Optional[str] = None
class UserOut(BaseModel):
username: str
email: EmailStr
full_name: Optional[str] = None
@app.post("/user/", response_model=UserOut)
async def create_user(user: UserIn):
return user
…我們已經將 response_model 聲明為了不包含密碼的 UserOut 模型:
from typing import Optional
from fastapi import FastAPI
from pydantic import BaseModel, EmailStr
app = FastAPI()
class UserIn(BaseModel):
username: str
password: str
email: EmailStr
full_name: Optional[str] = None
class UserOut(BaseModel):
username: str
email: EmailStr
full_name: Optional[str] = None
@app.post("/user/", response_model=UserOut)
async def create_user(user: UserIn):
return user
因此,FastAPI 將會負責過濾掉未在輸出模型中聲明的所有數據(使用 Pydantic)。
4、在文檔中查看
當你查看自動化文檔時,你可以檢查輸入模型和輸出模型是否都具有自己的 JSON Schema:
并且兩種模型都將在交互式 API 文檔中使用:
5、響應模型編碼參數
你的響應模型可以具有默認值,例如:
from typing import List, Optional
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: Optional[str] = None
price: float
tax: float = 10.5
tags: List[str] = []
items = {
"foo": {"name": "Foo", "price": 50.2},
"bar": {"name": "Bar", "description": "The bartenders", "price": 62, "tax": 20.2},
"baz": {"name": "Baz", "description": None, "price": 50.2, "tax": 10.5, "tags": []},
}
@app.get("/items/{item_id}", response_model=Item, response_model_exclude_unset=True)
async def read_item(item_id: str):
return items[item_id]
description: Optional[str] = None 具有默認值 None。
tax: float = 10.5 具有默認值 10.5.
tags: List[str] = [] 具有一個空列表作為默認值: [].
但如果它們并沒有存儲實際的值,你可能想從結果中忽略它們的默認值。
舉個例子,當你在 NoSQL 數據庫中保存了具有許多可選屬性的模型,但你又不想發送充滿默認值的很長的 JSON 響應。
6、使用 response_model_exclude_unset 參數(剔除默認值和空值)
你可以設置路徑操作裝飾器的 response_model_exclude_unset=True 參數:
from typing import List, Optional
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: Optional[str] = None
price: float
tax: float = 10.5
tags: List[str] = []
items = {
"foo": {"name": "Foo", "price": 50.2},
"bar": {"name": "Bar", "description": "The bartenders", "price": 62, "tax": 20.2},
"baz": {"name": "Baz", "description": None, "price": 50.2, "tax": 10.5, "tags": []},
}
@app.get("/items/{item_id}", response_model=Item, response_model_exclude_unset=True)
async def read_item(item_id: str):
return items[item_id]
然后響應中將不會包含那些默認值,而是僅有實際設置的值。
因此,如果你向路徑操作發送 ID 為 foo 的商品的請求,則響應(不包括默認值)將為:
{
"name": "Foo",
"price": 50.2
}
Info
FastAPI 通過 Pydantic 模型的 .dict() 配合 該方法的 exclude_unset 參數 來實現此功能。
Info
你還可以使用:
response_model_exclude_defaults=True
response_model_exclude_none=True
參考 Pydantic 文檔 中對 exclude_defaults 和 exclude_none 的描述。
7、默認值字段有實際值的數據
但是,如果你的數據在具有默認值的模型字段中有實際的值,例如 ID 為 bar 的項:
{
"name": "Bar",
"description": "The bartenders",
"price": 62,
"tax": 20.2
}
這些值將包含在響應中。
8、具有與默認值相同值的數據
如果數據具有與默認值相同的值,例如 ID 為 baz 的項:
{
"name": "Baz",
"description": None,
"price": 50.2,
"tax": 10.5,
"tags": []
}
即使 description、tax 和 tags 具有與默認值相同的值,FastAPI 足夠聰明 (實際上是 Pydantic 足夠聰明) 去認識到這一點,它們的值被顯式地所設定(而不是取自默認值)。
因此,它們將包含在 JSON 響應中。
Tip
請注意默認值可以是任何值,而不僅是None。
它們可以是一個列表([]),一個值為 10.5的 float,等等。
9、response_model_include 和 response_model_exclude
你還可以使用路徑操作裝飾器的 response_model_include 和 response_model_exclude 參數。
它們接收一個由屬性名稱 str 組成的 set 來包含(忽略其他的)或者排除(包含其他的)這些屬性。
如果你只有一個 Pydantic 模型,并且想要從輸出中移除一些數據,則可以使用這種快捷方法。
Tip
但是依然建議你使用上面提到的主意,使用多個類而不是這些參數。 這是因為即使使用 response_model_include 或 response_model_exclude 來省略某些屬性,在應用程序的 OpenAPI 定義(和文檔)中生成的 JSON Schema仍將是完整的模型。
這也適用于作用類似的 response_model_by_alias。
from typing import Optional
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: Optional[str] = None
price: float
tax: float = 10.5
items = {
"foo": {"name": "Foo", "price": 50.2},
"bar": {"name": "Bar", "description": "The Bar fighters", "price": 62, "tax": 20.2},
"baz": {
"name": "Baz",
"description": "There goes my baz",
"price": 50.2,
"tax": 10.5,
},
}
@app.get(
"/items/{item_id}/name",
response_model=Item,
response_model_include={"name", "description"},
)
async def read_item_name(item_id: str):
return items[item_id]大連人流醫院 http://mobile.84211111.cn/
@app.get("/items/{item_id}/public", response_model=Item, response_model_exclude={"tax"})
async def read_item_public_data(item_id: str):
return items[item_id]
Tip
{“name”, “description”} 語法創建一個具有這兩個值的 set。
等同于 set([“name”, “description”])。
10、使用 list 而不是 set
如果你忘記使用 set 而是使用 list 或 tuple,FastAPI 仍會將其轉換為 set 并且正常工作:
from typing import Optional
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: Optional[str] = None
price: float
tax: float = 10.5
items = {
"foo": {"name": "Foo", "price": 50.2},
"bar": {"name": "Bar", "description": "The Bar fighters", "price": 62, "tax": 20.2},
"baz": {
"name": "Baz",
"description": "There goes my baz",
"price": 50.2,
"tax": 10.5,
},
}
@app.get(
"/items/{item_id}/name",
response_model=Item,
response_model_include=["name", "description"],
)
async def read_item_name(item_id: str):
return items[item_id]
@app.get("/items/{item_id}/public", response_model=Item, response_model_exclude=["tax"])
async def read_item_public_data(item_id: str):
return items[item_id]
“如何使用參數聲明FastAPI響應模型”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。