Embed
만약 Body 에서 Request Body 내부에 Key 로 구분지어서 받고 싶다면 Embed=True 로 설정하면 된다. 다음과 같이 나온다
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(embed=True)]):
results = {"item_id": item_id, "item": item}
return results
이렇게 하면 아래와 같이 나온다.
{
"item": {
"name": "string",
"description": "string",
"price": 0,
"tax": 0
}
}
BaseModel로 QueryParam 사용하기
참고 자료
1. https://github.com/tiangolo/fastapi/discussions/6495
2. https://stackoverflow.com/questions/62468402/query-parameters-from-pydantic-model
만약 query param의 개수가 많다면 BaseModel로 선언하고, 아래와 같이 사용하면 된다.
class Foo(BaseModel):
num: int
char: str
@app.put("/items/{item_id}")
async def get_item(
query_parm: Foo = Depends(),
):
...
여기에 Field와 Query를 추가하면 metadata도 추가할 수 있다.
class Foo(BaseModel):
num: int = Field(
Query(
...,
description="숫자"
example=1,
),
)
char: str = Field(
Query(
...,
description="문자"
example="hello, world.",
min_length=1,
),
)
response_model_exclude_unset=True
값이 할당 되지 않은 예를 들면 Key가 없는 건 response 모델에서 뺀다.
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float = 10.5
tags: list[str] = []
items = {
"foo": {"name": "Foo", "price": 50.2},
"bar": {"name": "Bar", "description": "The bartenders", "price": 62, "tax": 20.2},
"baz": {"name": "Baz", "description": None, "price": 50.2, "tax": 10.5, "tags": []},
}
@app.get("/items/{item_id}", response_model=Item, response_model_exclude_unset=True)
async def read_item(item_id: str):
return items[item_id]
response 모델은 Item으로 정의되어 있지만, response를 보면 key 가 없는 foo의 경우엔 보이지 않는다.
{
"name": "Foo",
"price": 50.2
}
Response Model Union
class BaseItem(BaseModel):
description: str
type: str
class CarItem(BaseItem):
type: str = "car"
class PlaneItem(BaseItem):
type: str = "plane"
size: int
items = {
"item1": {"description": "All my friends drive a low rider", "type": "car"},
"item2": {
"description": "Music is my aeroplane, it's my aeroplane",
"type": "plane",
"size": 5,
},
}
@app.get("/items/{item_id}", response_model=Union[PlaneItem, CarItem])
async def read_item(item_id: str):
return items[item_id]
이런식으로 response_model을 선언하면 schema에선 다음과 같이 보인다.
'FastAPI' 카테고리의 다른 글
Router 의존성 주입과 API Func 의존성 주입 (0) | 2023.10.16 |
---|---|
FastAPI - Query Parameter에 Custom Validate 적용하기 (0) | 2023.09.02 |
Annotated (0) | 2023.08.03 |
QueryParameter (0) | 2023.08.02 |
FastAPI - PathParameter (0) | 2023.08.02 |