https://fastapi.tiangolo.com/tutorial/body-nested-models/
Body - Nested Models - FastAPI
Body - Nested Models With FastAPI, you can define, validate, document, and use arbitrarily deeply nested models (thanks to Pydantic). List fields You can define an attribute to be a subtype. For example, a Python list: This will make tags be a list, althou
fastapi.tiangolo.com
<FastAPI 공식문서 참조>
* FastAPI를 통해 임의의 깊은중첩모델을 정의, 검증, 문서화할 수 있다(Pydantic 덕분에).
1. List fields
파이썬 List와 같이, 한 속성을 subtype으로 정의할 수 있다.
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
tags: list = []
@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item):
results = {"item_id": item_id, "item": item}
return results
tags가 list 자료형 list로 정의되어 있다(내부 요소의 자료형은 선언하지 않았다).
1-1. List fields with type parameter
파이썬은 list 요소의 내부 자료형 혹은 내부 자료 매개변수를 지정할 수 있는 구체적인 방법이 있다.
1-1-1. Import List from typing
python 3.10+ 에선 아래와 같이 내부 자료형을 구체적으로 선언할 수 있다.
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
tags: list[str] = []
tags는 list 자료형이며, 내부는 string이어야 한다.
1-2. Set types
그런데 tag의 의미를 잘 생각해보면, tag는 고유한 목록을 가지고 있어야 하므로 집합 자료형을 쓸 필요가 있다. 따라서 list보단 set을 사용해보자.
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
tags: set[str] = set()
중복된 data를 받더라도 고유한 item으로 전환해 주는 자료형이다.
그리고 이건 주석이 될 수도, 문서가 될 수도 있다.
2. Nested Models
각각의 Pydantic model의 요소는 자료형을 가지고 있다.
그러나 그 자료형은 다른 Pydantic model이 될 수도 있다.
그래서 구체적인 유형의 이름, 자료형, 검증을 포함해 깊이 중첩된 JSON "객체"를 선언 할 수 있다.
이 모든 것은 임의적으로 중첩되있다.
2-1. Define a submodel
예시로, Image 라는 model을 정의해보자.
class Image(BaseModel):
url: str
name: str
2-2. Use the submodel as a type
그리고 이를 요소의 자료형으로써 사용할 수 있다.
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
tags: set[str] = set()
image: Image | None = None
Item의 attribute 중 하나인 image로 들어갔다.
그리고, FastAPI는 이에 해당하는 Item이라는 body를 아래와 같이 예상한다.
{
"name": "Foo",
"description": "The pretender",
"price": 42.0,
"tax": 3.2,
"tags": ["rock", "metal", "bar"],
"image": {
"url": "http://example.com/baz.jpg",
"name": "The Foo live"
}
}
이러한 선언을 하는 FastAPI를 통해,
- Editor support( 코드 완성 등등 )(중첩 모델이어도)
- 데이터 변환
- 데이터 검증
- 자동 문서화
의 기능을 얻을 수 있다.
2-3. Special types and validation
정수형, 문자형, 실수형과 같은 표준 자료형 외에도 Pydatic에는 불러올 수 있는 다향한 외부 자료형이 존재한다.
- HttpUrl
- URL인지 아닌지 검정해준다.
- list
- 리스트 자료형
- set
- 집합 자료형
등등이 있다.
아래는 HttpUrl 자료형에 대한 예제이다.
class Image(BaseModel):
url: HttpUrl
name: str
또한 Image model 자체를 list자료형의 인자로 받아 여러 model을 담게 선언할 수 도 있다.
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
tags: set[str] = set()
images: list[Image] | None = None
이때, FastAPI는 아래처럼 JSON body를 예상한다.
{
"name": "Foo",
"description": "The pretender",
"price": 42.0,
"tax": 3.2,
"tags": [
"rock",
"metal",
"bar"
],
"images": [
{
"url": "http://example.com/baz.jpg",
"name": "The Foo live"
},
{
"url": "http://example.com/dave.jpg",
"name": "The Baz"
}
]
}
3. Deeply nested models
아래처럼 임의적으로, 깊이 중첩시킨 모델을 선언할 수 도 있다.
from fastapi import FastAPI
from pydantic import BaseModel, HttpUrl
app = FastAPI()
class Image(BaseModel):
url: HttpUrl
name: str
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
tags: set[str] = set()
images: list[Image] | None = None
class Offer(BaseModel):
name: str
description: str | None = None
price: float
items: list[Item]
@app.post("/offers/")
async def create_offer(offer: Offer):
return offer
* Offer 속 Item, 그 속 Image가 있고, 각각 list자료형으로 받고 있음을 보자.
4. Bodies of pure lists
그냥 JSON array ( 혹은 Python list )가 가장 상위 수준에서 받는 JSON body 요소라면, 아래처럼 함수의 파라미터 타입을 선언하면 된다(Pydantic 모델에서 선언하는 것 처럼).
(*Python 3.9+ 기준.)
images: list[Image]
아래처럼 사용한다.
class Image(BaseModel):
url: HttpUrl
name: str
@app.post("/images/multiple/")
async def create_multiple_images(images: list[Image]):
return images
5. Bodies of arbitrary dict s
딕셔너리 자료형 또한 Body에 선언할 수 있다.
유효한 필드의 속성이 뭔지 알기 어려울 때(알 필요가 없을 때) 유용하게 사용할 수 있다.
다른 유용한 케이스로, 자료형을 미리 지정해서 자료형 검증을 할 수 있게 하는 것이다.
아래 예시로는 딕셔너리가 int형 키 / float형 값을 가져야 하는 검증과정을 거치게 선언하는 예제이다.
@app.post("/index-weights/")
async def create_index_weights(weights: dict[int, float]):
return weights
* JSON은 오직 str을 키로 가지는 것을 지원한다는 것을 명심하자.
그런데 Pydantic이 자동 데이터 형변환을 지원해 줄 것이다. int로 받아도 JSON으로 넘겨줄 땐 string으로 변환해 넘겨준다.
6. Recap
FastAPI는, 코드를 간결하고, 짧고, 우아하게 작성하면서도, Pydantic models를 통해 제공된 최대의 유동성을 가질 수 있다.
물론 다음과 같은 이점과 함께 :
- Editor support
- 데이터 형변환
- 데이터 검증
- 스키마 문서화
- 자동 문서
7. Reference
https://fastapi.tiangolo.com/ko/tutorial/body-nested-models/#__tabbed_2_1
Body - Nested Models - FastAPI
Body - Nested Models Warning The current page still doesn't have a translation for this language. But you can help translating it: Contributing. With FastAPI, you can define, validate, document, and use arbitrarily deeply nested models (thanks to Pydantic)
fastapi.tiangolo.com
'프레임워크 > FastAPI' 카테고리의 다른 글
[FastAPI] FastAPI [10] Extra Data Types (0) | 2023.04.03 |
---|---|
[FastAPI] FastAPI [9] Declare Request Example Data (0) | 2023.04.03 |
[FastAPI] FastAPI [7] Body - Fields (0) | 2023.03.27 |
[FastAPI] FastAPI [6] Body - Multiple Parameters (0) | 2023.03.27 |
[FastAPI] FastAPI [5] Path Parameters and Numeric Validations (0) | 2023.03.20 |