コンテンツへスキップ

データクラスの使用

FastAPIはPydanticの上に構築されており、リクエストとレスポンスを宣言するためにPydanticモデルを使用する方法を説明してきました。

しかしFastAPIは、dataclassesを同じように使用することもサポートしています。

from dataclasses import dataclass
from typing import Union

from fastapi import FastAPI


@dataclass
class Item:
    name: str
    price: float
    description: Union[str, None] = None
    tax: Union[float, None] = None


app = FastAPI()


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

これは、Pydanticdataclassesの内部サポートを持っているため、引き続きサポートされています。

したがって、Pydanticを明示的に使用しない上記のコードでも、FastAPIはPydanticを使用して、それらの標準データクラスをPydantic独自のデータクラス形式に変換しています。

そしてもちろん、同じものをサポートしています。

  • データ検証
  • データシリアル化
  • データドキュメントなど

これはPydanticモデルと同じように機能します。そして実際には、Pydanticを使用して内部で同じように実現されています。

情報

データクラスがPydanticモデルでできることすべてを実行できるわけではないことに注意してください。

そのため、Pydanticモデルを使用する必要がある場合もあります。

しかし、たくさんのデータクラスがある場合、FastAPIを使用してWeb APIを動かすのにこれらを使用するのは良いトリックです。🤓

response_modelにおけるデータクラス

response_modelパラメータでもdataclassesを使用できます。

from dataclasses import dataclass, field
from typing import List, Union

from fastapi import FastAPI


@dataclass
class Item:
    name: str
    price: float
    tags: List[str] = field(default_factory=list)
    description: Union[str, None] = None
    tax: Union[float, None] = None


app = FastAPI()


@app.get("/items/next", response_model=Item)
async def read_next_item():
    return {
        "name": "Island In The Moon",
        "price": 12.99,
        "description": "A place to be playin' and havin' fun",
        "tags": ["breater"],
    }

データクラスは自動的にPydanticデータクラスに変換されます。

これにより、そのスキーマはAPIドキュメントのユーザーインターフェースに表示されます。

ネストされたデータ構造におけるデータクラス

dataclassesを他の型アノテーションと組み合わせて、ネストされたデータ構造を作成することもできます。

場合によっては、Pydantic版のdataclassesを使用する必要があるかもしれません。たとえば、自動生成されたAPIドキュメントでエラーが発生した場合などです。

その場合、標準のdataclassespydantic.dataclassesに置き換えるだけで済みます。これはドロップイン置換です。

from dataclasses import field  # (1)
from typing import List, Union

from fastapi import FastAPI
from pydantic.dataclasses import dataclass  # (2)


@dataclass
class Item:
    name: str
    description: Union[str, None] = None


@dataclass
class Author:
    name: str
    items: List[Item] = field(default_factory=list)  # (3)


app = FastAPI()


@app.post("/authors/{author_id}/items/", response_model=Author)  # (4)
async def create_author_items(author_id: str, items: List[Item]):  # (5)
    return {"name": author_id, "items": items}  # (6)


@app.get("/authors/", response_model=List[Author])  # (7)
def get_authors():  # (8)
    return [  # (9)
        {
            "name": "Breaters",
            "items": [
                {
                    "name": "Island In The Moon",
                    "description": "A place to be playin' and havin' fun",
                },
                {"name": "Holy Buddies"},
            ],
        },
        {
            "name": "System of an Up",
            "items": [
                {
                    "name": "Salt",
                    "description": "The kombucha mushroom people's favorite",
                },
                {"name": "Pad Thai"},
                {
                    "name": "Lonely Night",
                    "description": "The mostests lonliest nightiest of allest",
                },
            ],
        },
    ]
  1. fieldは引き続き標準のdataclassesからインポートします。

  2. pydantic.dataclassesdataclassesのドロップイン置換です。

  3. AuthorデータクラスにはItemデータクラスのリストが含まれています。

  4. Authorデータクラスはresponse_modelパラメータとして使用されます。

  5. リクエストボディとしてデータクラスを持つ他の標準型アノテーションを使用できます。

    この場合、それはItemデータクラスのリストです。

  6. ここでは、データクラスのリストであるitemsを含む辞書を返しています。

    FastAPIは引き続きデータをJSONにシリアル化することができます。

  7. ここではresponse_modelAuthorデータクラスのリストの型アノテーションを使用しています。

    繰り返しになりますが、dataclassesと標準の型アノテーションを組み合わせることができます。

  8. このパス操作関数は、通常のdefを使用しており、async defではないことに注意してください。

    FastAPIでは、常に必要に応じてdefasync defを組み合わせることができます。

    どちらを使用するかについて再確認が必要な場合は、asyncawaitに関するドキュメントの「お急ぎですか?」セクションを確認してください。

  9. このパス操作関数はデータクラス(もちろんそうすることもできますが)ではなく、内部データを持つ辞書のリストを返しています。

    FastAPIはresponse_modelパラメータ(データクラスを含む)を使用してレスポンスを変換します。

dataclassesを他の型アノテーションと組み合わせて、さまざまな組み合わせで複雑なデータ構造を形成できます。

詳細については、上記のコード内アノテーションのヒントを確認してください。

詳細

dataclassesを他のPydanticモデルと組み合わせたり、それらを継承したり、独自のモデルに含めたりすることもできます。

詳細については、Pydanticのデータクラスに関するドキュメントを確認してください。

バージョン

これはFastAPIバージョン0.67.0以降で利用可能です。🔖