콘텐츠로 이동

Dataclasses 사용하기

🌐 Translation by AI and humans

This translation was made by AI guided by humans. 🤝

It could have mistakes of misunderstanding the original meaning, or looking unnatural, etc. 🤖

You can improve this translation by helping us guide the AI LLM better.

English version

FastAPI는 Pydantic 위에 구축되어 있으며, 지금까지는 Pydantic 모델을 사용해 요청과 응답을 선언하는 방법을 보여드렸습니다.

하지만 FastAPI는 dataclasses도 같은 방식으로 사용하는 것을 지원합니다:

from dataclasses import dataclass

from fastapi import FastAPI


@dataclass
class Item:
    name: str
    price: float
    description: str | None = None
    tax: float | None = None


app = FastAPI()


@app.post("/items/")
async def create_item(item: Item):
    return item
🤓 Other versions and variants
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

이는 Pydantic 덕분에 여전히 지원되는데, Pydantic이 dataclasses에 대한 내부 지원을 제공하기 때문입니다.

따라서 위 코드처럼 Pydantic을 명시적으로 사용하지 않더라도, FastAPI는 Pydantic을 사용해 표준 dataclasses를 Pydantic의 dataclasses 변형으로 변환합니다.

그리고 물론 다음과 같은 기능도 동일하게 지원합니다:

  • 데이터 검증
  • 데이터 직렬화
  • 데이터 문서화 등

이는 Pydantic 모델을 사용할 때와 같은 방식으로 동작합니다. 그리고 실제로도 내부적으로는 Pydantic을 사용해 같은 방식으로 구현됩니다.

정보

dataclasses는 Pydantic 모델이 할 수 있는 모든 것을 할 수는 없다는 점을 기억하세요.

그래서 여전히 Pydantic 모델을 사용해야 할 수도 있습니다.

하지만 이미 여러 dataclasses를 가지고 있다면, 이것은 FastAPI로 웹 API를 구동하는 데 그것들을 활용할 수 있는 좋은 방법입니다. 🤓

response_model에서 Dataclasses 사용하기

response_model 매개변수에서도 dataclasses를 사용할 수 있습니다:

from dataclasses import dataclass, field

from fastapi import FastAPI


@dataclass
class Item:
    name: str
    price: float
    tags: list[str] = field(default_factory=list)
    description: str | None = None
    tax: 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"],
    }
🤓 Other versions and variants
from dataclasses import dataclass, field
from typing import 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"],
    }

dataclass는 자동으로 Pydantic dataclass로 변환됩니다.

이렇게 하면 해당 스키마가 API docs 사용자 인터페이스에 표시됩니다:

중첩 데이터 구조에서 Dataclasses 사용하기

dataclasses를 다른 타입 애너테이션과 조합해 중첩 데이터 구조를 만들 수도 있습니다.

일부 경우에는 Pydantic 버전의 dataclasses를 사용해야 할 수도 있습니다. 예를 들어 자동 생성된 API 문서에서 오류가 발생하는 경우입니다.

그런 경우 표준 dataclasses를 드롭인 대체재인 pydantic.dataclasses로 간단히 바꾸면 됩니다:

from dataclasses import field  # (1)

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


@dataclass
class Item:
    name: str
    description: 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",
                },
            ],
        },
    ]
🤓 Other versions and variants
from dataclasses import field  # (1)
from typing import 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. 표준 dataclasses에서 field를 계속 임포트합니다.

  2. pydantic.dataclassesdataclasses의 드롭인 대체재입니다.

  3. Author dataclass에는 Item dataclasses의 리스트가 포함됩니다.

  4. Author dataclass가 response_model 매개변수로 사용됩니다.

  5. 요청 본문으로 dataclasses와 함께 다른 표준 타입 애너테이션을 사용할 수 있습니다.

    이 경우에는 Item dataclasses의 리스트입니다.

  6. 여기서는 dataclasses 리스트인 items를 포함하는 딕셔너리를 반환합니다.

    FastAPI는 여전히 데이터를 JSON으로 serializing할 수 있습니다.

  7. 여기서 response_modelAuthor dataclasses 리스트에 대한 타입 애너테이션을 사용합니다.

    다시 말해, dataclasses를 표준 타입 애너테이션과 조합할 수 있습니다.

  8. 경로 처리 함수async def 대신 일반 def를 사용하고 있다는 점에 주목하세요.

    언제나처럼 FastAPI에서는 필요에 따라 defasync def를 조합해 사용할 수 있습니다.

    어떤 것을 언제 사용해야 하는지 다시 확인하고 싶다면, asyncawait{.internal-link target=blank} 문서의 _"급하신가요?" 섹션을 확인하세요.

  9. 경로 처리 함수는 dataclasses를(물론 반환할 수도 있지만) 반환하지 않고, 내부 데이터를 담은 딕셔너리들의 리스트를 반환합니다.

    FastAPI는 response_model 매개변수(dataclasses 포함)를 사용해 응답을 변환합니다.

dataclasses는 다른 타입 애너테이션과 매우 다양한 조합으로 결합해 복잡한 데이터 구조를 구성할 수 있습니다.

더 구체적인 내용은 위 코드 내 애너테이션 팁을 확인하세요.

더 알아보기

dataclasses를 다른 Pydantic 모델과 조합하거나, 이를 상속하거나, 여러분의 모델에 포함하는 등의 작업도 할 수 있습니다.

자세한 내용은 dataclasses에 관한 Pydantic 문서를 참고하세요.

버전

이 기능은 FastAPI 0.67.0 버전부터 사용할 수 있습니다. 🔖