FastAPI基礎学習(14)Responseモデル

23737 ワード

作者:マイクオムレツ出典: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": "[email protected]",
    "full_name": "full_name"
}

出力結果は次のとおりです.
{
    "username": "user",
    "email": "[email protected]",
    "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_includeとresponse_model_exclude


この2つのパラメータはResponseモデルの一部の属性集合を受信し,それぞれ(残りを除外する)と(残りを含む)の集合を含む属性を表す.
実際の作業では、この2つのパラメータをできるだけ少なく利用するのではなく、異なるクラスが異なるデータニーズを表すことを宣言する必要があります.これにより、データのメンテナンスと論理の明確化が容易になります.
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タイプ(2つのタイプを含む)であり、実際の戻り結果は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}