개요
최근 FastAPI로 API 개발을 하고 있는데, API 문서에 API 요청 방법에 대한 예시가 있으면 좋을 것 같다. 확인해 보니 요청 데이터 예시를 추가할 수 있는 방법이 있어 이번 글을 통해 정리해두려고 한다.
Pydantic 모델에 추가
Pydantic 모델에 json_schema_extra 설정으로 examples을 추가하면 예시 request body를 지정할 수 있다.
예시 request body는 딕셔너리 리스트로 전달한다. (여러 개를 전달해도 API 문서에는 하나만 표시되는 것 같다.)
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
model_config = {
"json_schema_extra": {
"examples": [{
"name": "Foo",
"description": "A very nice Item",
"price": 35.4,
"tax": 3.2,
}
]
}
}
@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item):
results = {"item_id": item_id, "item": item}
return results
JSON Schema에 추가 - examples
Pydantic 모델이 아닌 JSON 스키마에 examples를 지정하여 요청 데이터 예시를 지정할 수 있다. request body 뿐만 아니라 Path, Query, Header, Cookie, Body, Form, File 전부 요청 데이터 예시를 지정할 수 있다.
JSON 스키마에 지정할 때는 함수의 매개변수를 정의할 때 Pydantic 모델과 examples 매개변수를 지정한 Body를 typing.Annotated로 표시하면 된다. examples 매개변수는 딕셔너리 리스트로 전달한다. 여러 개의 딕셔너리를 전달해도 하나만 확인할 수 있는 것 같다.
from typing import Annotated
from fastapi import Body, FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
@app.put("/items/{item_id}")
async def update_item(item_id: int,
item: Annotated[
Item,
Body(examples=[
{
"name": "Test",
"description": "Item",
"price": 100.0,
"tax": 1.5,
}
],
),
],
):
results = {"item_id": item_id, "item": item}
return results
이 설정은 redoc에는 반영이 안 되는 것 같다.
OpenAPI JSON Schema에 추가 - openapi_examples
또는 OpenAPI JSON 스키마에 추가할 수도 있다. JSON 스키마에 추가하는 것과 동일한 방식으로 추가하되 openapi_examples라는 매개변수로 요청 데이터 예시를 지정해야 한다. openapi_examples에는 예시 request body의 이름을 키로 하고, request body 내용을 값으로 하는 딕셔너리로 전달한다.
추가로 다른 설정과 다르게 openapi_examples는 여러 개의 요청 데이터 예시를 지정할 수 있다.
@app.put("/items/{item_id}")
async def update_item(
*,
item_id: int,
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",
},
}
},
),
],
):
results = {"item_id": item_id, "item": item}
return results
참고 문서
https://fastapi.tiangolo.com/ko/tutorial/schema-extra-example/
[fastapi] Field를 사용하여 Request Body로 데이터 받기