본문 바로가기
Fast API/fastapi배우기

Fast API 배우기 7부 - Field 클래스

by 붕어사랑 티스토리 2021. 11. 1.
반응형

Field 클래스란

쿼리 파라미터를 Query클래스로 다루고

패스 파라미터를 Path클래스로 다루고

리퀘스트 바디를 Body 클래스로 다루듯이

 

리퀘스트 바디 안에 있는 Metadata를 Feild 클래스로 세세하게 다룰 수 있다

 

from typing import Optional
from fastapi import Body, FastAPI

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")
    tax: Optional[float] = None


@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item = Body(..., embed=True)):
    results = {"item_id": item_id, "item": item}
    return results

 

아래 코드는 위코드에서 feild 사용 예제이다. ...은 required를 의미하고 gt는 greater than을 의마하는것을 우리는 이전에배워서 알고있다.

    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")

 

 

 

 

List Field

 

메타데이터로 List 필드를 선언해 줄 수 있다.

from typing import Optional

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()


class Item(BaseModel):
    name: str
    description: Optional[str] = None
    price: float
    tax: Optional[float] = 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

 

아래와 같이 List에 type paramter를 넣으면 리스트안에 들어갈 타입을 제한할 수 있음

from typing import List, Optional


from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()


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


@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item):
    results = {"item_id": item_id, "item": item}
    return results

 

 

Set field

위에 예제에서 tags는 list로 선언되어있다. 그런대 만약 tags가 중복되지 않게하려면? set을 이용하면 된다.

from typing import Optional, Set


from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()


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

    tags: Set[str] = set()



@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item):
    results = {"item_id": item_id, "item": item}
    return results

 

 

 

 

Nested Model

하나의 모델은 다른 모델 안에 nested 될 수 있다.

 

from typing import Optional, Set

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()


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



@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item):
    results = {"item_id": item_id, "item": item}
    return results

 

 

위 예제에서 리퀘스트 바디는 아래와 같은 형태를 이룬다.

 

{
    "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"
    }
}

 

 

 

 

Special Type의 Field

위에서 우리는 Field에 타입을 강제할때 str, int, float같은 파이썬의 기본 자료형을 사용한 예제를 보았다.

fast api는 이를 넘어서 str을 상속하는 type또한 fields로 지정해 줄수 있다.

 

자세한 내용은 아래 링크에 나와있다.

https://pydantic-docs.helpmanual.io/usage/types/

 

Field Types - pydantic

Field Types Where possible pydantic uses standard library types to define fields, thus smoothing the learning curve. For many useful applications, however, no standard library type exists, so pydantic implements many commonly used types. If no existing typ

pydantic-docs.helpmanual.io

 

 

 

예제를 하나 들면

 

 

가령 Image라는 모델이 있다 하자. 이 모델은 이미지의 경로와 이미지 이름을 담고있다.

 

경로와 이름을 str로 설정했다 치자. 여기서 우리는 경로를 str이 아닌 Pydantic의 HttpUrl로 선언 해 줄 수 있다.

 

 

from typing import Optional, Set

from fastapi import FastAPI

from pydantic import BaseModel, HttpUrl


app = FastAPI()


class Image(BaseModel):

    url: HttpUrl

    name: str


class Item(BaseModel):
    name: str
    description: Optional[str] = None
    price: float
    tax: Optional[float] = None
    tags: Set[str] = set()
    image: Optional[Image] = None


@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item):
    results = {"item_id": item_id, "item": item}
    return results

 

 

 

 

 

Model을 List의 타입으로 강제화 하기

 

아래 예제처럼 List의 타입 강제화로 Model을 사용할 수도 있다.

from typing import List, Optional, Set

from fastapi import FastAPI
from pydantic import BaseModel, HttpUrl

app = FastAPI()


class Image(BaseModel):
    url: HttpUrl
    name: str


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

    images: Optional[List[Image]] = None



@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item):
    results = {"item_id": item_id, "item": item}
    return results
    images: Optional[List[Image]] = None

 

 

json형태는 아래와 같이 나온다.

 

{
    "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"
        }
    ]
}

 

반응형

 

 

중첩 Nested

 

아래처럼 Nested를 중첩하려 사용할 수도 있다.

from typing import List, Optional, Set

from fastapi import FastAPI
from pydantic import BaseModel, HttpUrl

app = FastAPI()



class Image(BaseModel):

    url: HttpUrl
    name: str



class Item(BaseModel):

    name: str
    description: Optional[str] = None
    price: float
    tax: Optional[float] = None
    tags: Set[str] = set()

    images: Optional[List[Image]] = None




class Offer(BaseModel):

    name: str
    description: Optional[str] = None
    price: float

    items: List[Item]



@app.post("/offers/")
async def create_offer(offer: Offer):
    return offer

 

 

Body에 순수 List 사용하기

만약 바디로 json list를 받고 싶을경우 아래처럼 사용 가능하다.

from typing import List

from fastapi import FastAPI
from pydantic import BaseModel, HttpUrl

app = FastAPI()


class Image(BaseModel):
    url: HttpUrl
    name: str


@app.post("/images/multiple/")

async def create_multiple_images(images: List[Image]):

    return images
images: List[Image]

 

 

 

Dict를 바디에 사용하기

 

아래처럼 사전형 자료형도 바디에 사용 가능하다.

 

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

 

 

반응형

댓글