FastAPI Response(一) Response模型


作者:麥克煎蛋   出處:https://www.cnblogs.com/mazhiyong/ 轉載請保留這段聲明,謝謝!

 

一、Response模型

在路徑操作中,我們可以用參數response_model來聲明Response模型。

from typing import List
from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()


class Item(BaseModel):
    name: str
    description: str = None
    price: float
    tax: float = None
    tags: List[str] = []


@app.post("/items/", response_model=Item)
async def create_item(item: Item):
    return item

注意response_model是裝飾器方法(get,post等)的參數。

 

Response模型可以是一個Pydantic模型,也可以是一個Pydantic模型的列表,例如List[Item]。

支持任意路徑操作:

@app.get()
@app.post()
@app.put()
@app.delete()

 

FastAPI利用Response模型實現以下功能:

1、將輸出數據轉換成聲明的Response模型。

2、對數據進行校驗

3、生成自動化文檔

4、(最重要的)限制輸出數據只能是所聲明的Response模型。

二、輸入輸出模型示例

# 可能需要安裝email-validator --> pip install email-validator 

from
fastapi import FastAPI from pydantic import BaseModel, EmailStr app = FastAPI() class UserIn(BaseModel): username: str password: str email: EmailStr full_name: str = None class UserOut(BaseModel): username: str email: EmailStr full_name: str = None @app.post("/user/", response_model=UserOut) async def create_user(*, user: UserIn): return user

如上所示,雖然路徑操作函數返回的結果是user(包含了password),但我們聲明的Response模型是UserOut(不包含password)。

FastAPI會過濾掉所有不在輸出模型中的數據,因此最終的輸出結果里並沒有password。

如果輸入內容如下:

{
    "username": "user",
    "password": "1234",
    "email": "user@qq.com",
    "full_name": "full_name"
}

那么輸出結果為:

{
    "username": "user",
    "email": "user@qq.com",
    "full_name": "full_name"
}

三、Response模型參數

1、Response模型可以有缺省值。

from typing import List

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()


class Item(BaseModel):
    name: str
    description: 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]

2、返回實際有效數據

有時候我們只想返回被真正設置過的數據,而忽略其他未被設置過的或者缺省數據。

我們可以用參數response_model_exclude_unset來實現這個目的。如上所示代碼。

# 訪問:
http://127.0.0.1:8000/items/foo

# 返回結果:
{
    "name": "Foo", "price": 50.2 }

3、參數 response_model_includeresponse_model_exclude

這兩個參數接收Response模型的部分屬性集合,分別表示包含(排除剩下的)和排除(包含剩下的)集合里的屬性。

在實際工作中,我們應該盡量少利用這兩個參數,而是應該聲明不同的類表示不同的數據需求,這樣更利於數據維護和邏輯清晰。

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()


class Item(BaseModel):
    name: str
    description: 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]

四、Response聯合模型

我們可以聲明Response模型是一個Union類型(包含兩種類型),實際返回結果可以是Union其中任何一個。

from typing import Union from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()


class BaseItem(BaseModel):
    description: str
    type: str


class CarItem(BaseItem): type = "car"


class PlaneItem(BaseItem): type = "plane" size: int


items = {
    "item1": {"description": "All my friends drive a low rider", "type": "car"},
    "item2": {
        "description": "Music is my aeroplane, it's my aeroplane",
        "type": "plane",
        "size": 5,
    },
}


@app.get("/items/{item_id}", response_model=Union[PlaneItem, CarItem])
async def read_item(item_id: str):
    return items[item_id]

這里PlaneItem、CarItem均從BaseItem繼承而來,提高代碼復用,也便於代碼維護。

五、Response列表模型

Response模型也可以是一個列表。

from typing import List from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()


class Item(BaseModel):
    name: str
    description: str


items = [
    {"name": "Foo", "description": "There comes my hero"},
    {"name": "Red", "description": "It's my aeroplane"},
]


@app.get("/items/", response_model=List[Item])
async def read_items():
    return items

六、Response字典模型

我們也可以不用Pydantic模型,而是直接基於字典來聲明Response模型。

from typing import Dict from fastapi import FastAPI

app = FastAPI()


@app.get("/keyword-weights/", response_model=Dict[str, float])
async def read_keyword_weights():
    return {"foo": 2.3, "bar": 3.4}

 


免責聲明!

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



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