본문 바로가기

Fastapi

내맘대로 Fastapi docs 정리(Pydantic data types, Pydantic Nested Models)

Pydantic

from pydantic import BaseModel, Field
app = FastAPI()
class Item(BaseModel):
    name: str
    description: Optional[str] = Field(
        None, title="The description of the item", max_length=300
    )
    price: float = Field(..., gt=0, description="The price must be greater than zero", example="a")
    tax: Optional[float] = None
  • query, path, body parameter와 같이 baseModel안에서도 똑같이 쓸 수 있는데 그것은 Field이다.

 

class Item(BaseModel):
    name: str
    description: Optional[str] = None
    price: float
    tax: Optional[float] = None
    tags: List[str] = []
  • python 기본 list, dict, tuple, Set를 쓸 수 있다. (set같은 경우는  Set[str] = set())
class Image(BaseModel):
    url: str
    name: str
class Item(BaseModel):
    name: str
    description: Optional[str] = None
    price: float
    tax: Optional[float] = None
    tags: Set[str] = []
    image: Optional[Image] = None
  • nested model로 쓸 수 있다.
    {
        "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"
        }
    }

 

from pydantic import BaseModel, HttpUrl
class Image(BaseModel):
    url: HttpUrl
  •  HttpUrl같이 str을 상속하는 여러 자료형이 존재한다. 

 

 

class Image(BaseModel):
    url: HttpUrl
    name: str
    
class Item(BaseModel):
	images: Optional[List[Image]] = None
  • {
        "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"
            }
        ]
    }
from typing import Dict

from fastapi import FastAPI

app = FastAPI()

@app.post("/index-weights/")
async def create_index_weights(weights: Dict[int, float]):
    return weights
  • Dict[int, float]은 key: int, value: float을 가지며, python 3.9이상에서는 내장 자료형 dict[int, float]을 쓰면된다.
  • json은 오로지 string의 key값을 지니는데, 위의 int key처럼 pydantic이 알아서 data conversion을 해준다.

 

 

Example with openapi (example)

class Item(BaseModel):
    name: str
    description: Optional[str] = None
    price: float
    tax: Optional[float] = None

    class Config:
        schema_extra = {
            "example": {
                "name": "Foo",
                "description": "A very nice Item",
                "price": 35.4,
                "tax": 3.2,
            }
        }
  • pydantic schema를 customization할 수 있는데 위의 예시는 추가적으로 넣을 key:value를 넣어주는 것이다.
  • 단순히 pydantic 변수나, dict()로는 return값을 볼 수 없지만,  api docs의 schema에 나타나고, schema_json함수를 써야 추가적인 정보를 볼 수 있다. 
  • 관련 링크 -> https://pydantic-docs.helpmanual.io/usage/schema/#schema-customization
 

Schema - pydantic

Schema Pydantic allows auto creation of JSON Schemas from models: from enum import Enum from pydantic import BaseModel, Field class FooBar(BaseModel): count: int size: float = None class Gender(str, Enum): male = 'male' female = 'female' other = 'other' no

pydantic-docs.helpmanual.io

 

 

  • Path()
  • Query()
  • Header()
  • Cookie()
  • Body()
  • Form()
  • File()
  • Field()
  • 다음과 같은 api를 사용할 때 example, examples를 파라미터로 사용할 수있음.

 

# Multiple examples
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",
                },
            },
        }

 

  • 다음과 같이 다양한 examples를 사용하고 싶다면 위와같이 정의하면 아래처럼 swagger에서 선택해서 볼 수 있다.

 

 

Extra Data Types

from datetime import datetime, time, timedelta
from typing import Optional
from uuid import UUID

from fastapi import Body, FastAPI
app = FastAPI()

@app.put("/items/{item_id}")
async def read_items(
    item_id: UUID,
    start_datetime: Optional[datetime] = Body(None),
    end_datetime: Optional[datetime] = Body(None),
    repeat_at: Optional[time] = Body(None),
    process_after: Optional[timedelta] = Body(None),
):

 

 

  • extra data types -> Decimal, bytes, frozenset, datetime.timedelta, datetime.time, datetime.date, datetime.datetime, UUID
  • 예를 들어 datatime 자료형 끼리는 서로 사칙연산이 가능하다