데이터클래스 사용하기
데이터클래스 사용하기 (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 문서에 오류가 있을 때요.
그런 경우 표준 dataclasses를 pydantic.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",
},
],
},
]
-
여전히 표준
dataclasses에서field를 임포트해요. -
pydantic.dataclasses는dataclasses의 드롭인 교체품이에요. -
Authordataclass는Itemdataclass들의 목록을 포함해요. -
Authordataclass는response_model파라미터로 사용돼요. -
dataclasses와 함께 다른 표준 타입 애너테이션을 요청 본문으로 사용할 수 있어요.
이 경우엔
Itemdataclass들의 목록이에요. -
여기서는 내부 데이터가 담긴 dataclass 목록인
items를 포함한 딕셔너리를 돌려주고 있어요.FastAPI는 여전히 데이터를 JSON으로 직렬화할 수 있어요.
-
여기서
response_model은Authordataclass들의 목록 타입 애너테이션을 사용하고 있어요.다시 말하면,
dataclasses를 표준 타입 애너테이션과 결합할 수 있어요. -
이 path operation 함수가
async def대신 일반def를 사용한다는 점에 주목하세요.항상 그렇듯, FastAPI에서는 필요에 따라
def와async def를 조합해서 쓸 수 있어요.언제 어떤 것을 써야 하는지 다시 보고 싶다면,
async와await문서의 "In a hurry?" 섹션을 확인해 보세요. -
이 path operation 함수는 dataclasses를 돌려주는 게 아니라(그럴 수도 있지만) 내부 데이터가 담긴 딕셔너리 목록을 돌려주고 있어요.
FastAPI는
response_model파라미터(dataclasses를 포함하는)를 사용해서 응답을 변환해요.
dataclasses를 다른 타입 애너테이션과 다양한 조합으로 결합해서 복잡한 데이터 구조를 만들 수 있어요.
위의 코드 안 애너테이션 팁들에서 더 구체적인 세부 사항을 확인해 보세요.
Pydantic 데이터클래스에 대해 더 알아보기
dataclasses를 다른 Pydantic 모델과 결합하거나, 이들로부터 상속받거나, 여러분의 모델에 포함하는 등의 일도 할 수 있어요.
더 자세히 알아보려면 Pydantic의 dataclasses 문서를 확인하세요.
버전
이 기능은 FastAPI 버전 0.67.0부터 사용할 수 있어요. 🔖
더 알아보기 (Learn more)
이 문서는 FastAPI 공식 문서 - Using Dataclasses를 한국어로 정리한 번역이에요. 원문에서 최신 내용과 더 다양한 예시를 확인하세요.