아래 코드는 pydantic v2 이상에서 동작한다.
FastAPI는 Python의 Pydantic을 활용하여 데이터를 쉽게 검증하고 처리할 수 있는 강력한 기능을 제공한다. Pydantic의 v2가 등장하면서 여러 개선 사항이 도입되었고, 이에 따라 FastAPI에서도 Pydantic v2를 활용한 예시(example
) 설정이 더 유연해졌다.
1. Pydantic v2의 주요 변경 사항
Pydantic v2에서는 모델 정의와 유효성 검사 방식에 몇 가지 주요 변경 사항이 있다. 특히, 데이터 클래스 스타일의 필드 정의가 강조되었으며, Field
의 사용 방식도 다소 변화가 있었다. 그럼에도 불구하고, example
을 추가하는 방식은 이전 버전과 유사하다.
2. Pydantic v2에서의 기본 Example 설정
Pydantic 모델에 example
을 설정하는 가장 기본적인 방법부터 시작해보자.
from fastapi import FastAPI
from pydantic import BaseModel, Field
app = FastAPI()
class Item(BaseModel):
name: str = Field(..., example="Apple MacBook Pro")
description: str | None = Field(None, example="A high-end laptop from Apple")
price: float = Field(..., example=1999.99)
tax: float | None = Field(None, example=19.99)
@app.post("/items/")
async def create_item(item: Item):
return item
위 코드에서 각 필드에 example
을 추가했다. Pydantic v2에서도 Field
를 사용하여 필드별로 예시값을 정의할 수 있다.
- name: "Apple MacBook Pro"라는 예시를 추가했다.
- description: "A high-end laptop from Apple"이라는 설명을 예시로 추가했다.
- price: 1999.99라는 가격을 예시로 추가했다.
- tax: 19.99라는 세율을 예시로 설정했다.
이와 같이 설정된 예시는 FastAPI의 자동 생성 API 문서에서 바로 확인할 수 있다.
3. 전체 모델에 Example 추가하기
Pydantic v1에서도 모델 전체에 대한 예시를 제공하는 방법은 Config
클래스를 활용하는 방식으로 가능했지만 v2에서는 model_config에서 json_schema_extra
를 사용하여 모델 수준에서 예시를 지정할 수 있다.
from fastapi import FastAPI
from pydantic import BaseModel, Field
app = FastAPI()
class Item(BaseModel):
name: str = Field(...)
description: str | None = Field(None)
price: float = Field(...)
tax: float | None = Field(None)
model_config = {
"json_schema_extra": {
"examples": [
{
"name": "Foo",
"description": "A very nice Item",
"price": 35.4,
"tax": 3.2,
}
]
}
}
@app.post("/items/")
async def create_item(item: Item):
return item
여기서는 json_schema_extra
를 통해 모델 전체에 대한 예시를 제공한다. 이 방식으로 설정된 예시는 API 문서에 명확히 표시되어, 개발자나 사용자들이 쉽게 참고할 수 있다.
4. openapi_examples를 통한 복수의 Example 추가하기
Pydantic v2에서도 OpenAPI의 기능을 활용하여 하나의 모델에 대해 여러 개의 예시를 제공할 수 있다. openapi_examples
를 통해 다양한 시나리오에 맞는 예시를 설정할 수 있다.
from fastapi import FastAPI
from pydantic import BaseModel, Field
app = FastAPI()
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
async def create_item(
item: Annotated[
Item,
Body(
openapi_examples={
"normal": {
"summary": "A normal example",
"description": "A **normal** item works correctly.",
"value": {
"name": "Foo",
"description": "A very nice Item",
"price": 35.4,
"tax": 3.2,
},
},
"converted": {
"summary": "An example with converted data",
"description": "FastAPI can convert price `strings` to actual `numbers` automatically",
"value": {
"name": "Bar",
"price": "35.4",
},
},
"invalid": {
"summary": "Invalid data is rejected with an error",
"value": {
"name": "Baz",
"price": "thirty five point four",
},
},
}
),
]
):
return item
위 코드에서는 openapi_examples
의 examples
를 통해 세 가지 다른 예시를 제공하고 있다.
/docs로 접속하여 swagger api를 확인해보면 3가지가 표시되는 것을 확인할 수 있다.
5. Example 사용의 장점
- 더 나은 문서화:
example
을 통해 API 문서에서 입력 데이터의 예시를 제공함으로써, 사용자가 어떤 형식으로 데이터를 제공해야 하는지 쉽게 이해할 수 있다. - 테스트 용이성: 예시 데이터는 개발자와 테스터들이 API를 다양한 시나리오에서 쉽게 테스트할 수 있도록 도와준다.
- 개발자 경험 향상: 명확한 예시는 개발자가 API를 사용할 때 혼동을 줄이고, 개발 속도를 높여준다.