Python/FastAPI

[FastAPI] (5) FastAPI Validation - Path, Query, Field

yubi5050 2022. 10. 26. 18:29

Path, Query, Field

Pydantic의 데이터 검증에 덧붙여 
 
FastAPI의 Field, Path, Query를 사용해 매개변수를 명시적으로 정의하고, 좀더 세부적인 데이터 검증이 가능하다.
  • gt, ge, lt, le : 숫자 대소비교 (greater than, less than 등)
  • min_length, max_length : 문자열 길이 값
  • min_items, max_items : List, Set등의 Collection 객체 담당
  • regex 등 도 사용 가능
 
방법에는 크게 2가지가 존재
  • 함수 인자에서 FastAPI의 Path, Query를 활용하는 방법
  • BaseModel을 상속한 Class에서 Pydantic의 Field 사용 방법

 

예제 공통 부분 - 임의 데이터셋 생성

예제 1과 예제 2에서 활용할 inventory 라는 임의 데이터셋을 생성
from fastapi import FastAPI, Query, Path, status
from pydantic import BaseModel, Field
from typing import List

app = FastAPI()

inventory = [
    {
        "id": 1,
        'user_id':2,
        "name": "무기",
        "price": 250.0,
    },
    {
        "id": 2,
        'user_id':3,
        "name": "방어구",
        "price": 500.0,
    },]

 

1) 함수에서 정의 하기 - Path, Query 활용

함수 인자에서 FastAPI의 Path, Query를 활용하여 구체적으로 명시한다.

# v1 - 함수에서 작성 : user의 inventory 조회
# http://127.0.0.1:8000/users/2/inventory?name=무기
class Item(BaseModel):
    id: int 
    user_id: int
    name: str
    price: float

@app.get("/users/{user_id}/inventory", response_model=Item, response_model_exclude={'id', 'user_id'})
def get_item(
    user_id: int = Path(..., gt=0, title="사용자 id"), # ...은 필수라는 뜻 <-> None
    name: str = Query(None, min_length=1, max_length=10, title="아이템 이름"),
    ):
    result = ''
    for item in inventory:
        if (user_id == item['user_id']) and (name == item['name']):
            result = item
            break
    result = [item for item in inventory if (user_id == item['user_id']) and (name == item['name'])]
    return result[0]
 
 

2) BaseModel을 상속받은 Class에서 정의 하기 - Field

BaseModel을 상속한 Class에서 Pydantic의 Field 사용 방법

# v2
class Item2(BaseModel):
    name: str = Field(..., min_length=1, max_length=100, title="이름")
    price: float = Field(None, ge=0)
    amount: int = Field(default=1, gt=0, le=300, title="수량",)

# http://127.0.0.1:8000/users/2/item body={ "name":"무기", "price":100.5, "amount":200}
@app.post("/users/{user_id}/item")
def create_item(item: Item2):
    inventory.append(item)
    return inventory