데이터클래스 사용하기

데이터클래스 사용하기 (Using Dataclasses)

FastAPI는 Pydantic 위에 만들어져 있어요. 그리고 지금까지 Pydantic 모델로 요청과 응답을 선언하는 방법을 보여드렸죠.

하지만 FastAPI는 dataclasses도 같은 방식으로 사용하는 걸 지원해요.

Python 3.10+

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

이건 Pydantic 덕분에 계속 지원돼요. Pydantic이 dataclasses에 대한 내부 지원을 갖고 있기 때문이에요.

그래서 위처럼 Pydantic을 명시적으로 사용하지 않는 코드에서도 FastAPI는 Pydantic을 사용해서 그 표준 dataclasses를 Pydantic만의 dataclasses 버전으로 변환해요.

그리고 당연히 같은 것들을 지원해요.

  • 데이터 검증(data validation)
  • 데이터 직렬화(data serialization)
  • 데이터 문서화(data documentation) 등

이건 Pydantic 모델과 같은 방식으로 동작해요. 그리고 사실 밑에서도 같은 방식으로, Pydantic을 사용해서 이루어져요.

참고

dataclasses는 Pydantic 모델이 할 수 있는 모든 것을 할 수 있는 건 아니라는 점을 기억하세요.

그래서 여전히 Pydantic 모델이 필요할 수도 있어요.

하지만 주변에 dataclasses가 많이 있다면, FastAPI로 웹 API를 구동하는 데 사용할 수 있는 좋은 꼼수예요. 🤓

출처: 공식문서

response_model 안의 데이터클래스

respons_model 파라미터에서도 dataclasses를 사용할 수 있어요.

Python 3.10+

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"],
    }

dataclass는 자동으로 Pydantic dataclass로 변환돼요.

이렇게 하면 그 스키마가 API 문서 사용자 인터페이스에 나타나요.

중첩 데이터 구조 안의 데이터클래스

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

경우에 따라 여전히 Pydantic 버전의 dataclasses를 사용해야 할 수도 있어요. 예를 들어 자동 생성된 API 문서에 오류가 있을 때요.

그런 경우 표준 dataclassespydantic.dataclasses로 바꾸기만 하면 돼요. 이건 드롭인(drop-in, 바로 대체 가능한) 교체품이에요.

Python 3.10+

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",
                },
            ],
        },
    ]
  1. 여전히 표준 dataclasses에서 field를 임포트해요.

  2. pydantic.dataclassesdataclasses의 드롭인 교체품이에요.

  3. Author dataclass는 Item dataclass들의 목록을 포함해요.

  4. Author dataclass는 response_model 파라미터로 사용돼요.

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

    이 경우엔 Item dataclass들의 목록이에요.

  6. 여기서는 내부 데이터가 담긴 dataclass 목록인 items를 포함한 딕셔너리를 돌려주고 있어요.

    FastAPI는 여전히 데이터를 JSON으로 직렬화할 수 있어요.

  7. 여기서 response_modelAuthor dataclass들의 목록 타입 애너테이션을 사용하고 있어요.

    다시 말하면, dataclasses를 표준 타입 애너테이션과 결합할 수 있어요.

  8. path operation 함수async def 대신 일반 def를 사용한다는 점에 주목하세요.

    항상 그렇듯, FastAPI에서는 필요에 따라 defasync def를 조합해서 쓸 수 있어요.

    언제 어떤 것을 써야 하는지 다시 보고 싶다면, asyncawait 문서의 "In a hurry?" 섹션을 확인해 보세요.

  9. path operation 함수는 dataclasses를 돌려주는 게 아니라(그럴 수도 있지만) 내부 데이터가 담긴 딕셔너리 목록을 돌려주고 있어요.

    FastAPI는 response_model 파라미터(dataclasses를 포함하는)를 사용해서 응답을 변환해요.

dataclasses를 다른 타입 애너테이션과 다양한 조합으로 결합해서 복잡한 데이터 구조를 만들 수 있어요.

위의 코드 안 애너테이션 팁들에서 더 구체적인 세부 사항을 확인해 보세요.

Pydantic 데이터클래스에 대해 더 알아보기

dataclasses를 다른 Pydantic 모델과 결합하거나, 이들로부터 상속받거나, 여러분의 모델에 포함하는 등의 일도 할 수 있어요.

더 자세히 알아보려면 Pydantic의 dataclasses 문서를 확인하세요.

버전

이 기능은 FastAPI 버전 0.67.0부터 사용할 수 있어요. 🔖

더 알아보기 (Learn more)

이 문서는 FastAPI 공식 문서 - Using Dataclasses를 한국어로 정리한 번역이에요. 원문에서 최신 내용과 더 다양한 예시를 확인하세요.