FastAPI

FastAPI 데이터 검증

깽원 2024. 1. 25. 01:05

FastAPI의 장점 중 하나는 데이터의 검증을 자동으로 해준다는 점입니다.

 

함수를 정의할 때, 각 매개변수가 경로 매개변수인지 아니면 쿼리 매개변수 인지를 명시하지 않았었습니다. 따로 명시하지 않았던 이유는 FastAPI에서 자동으로 인지했기 때문입니다.

 

하지만, Path(), Query() 함수를 사용하면, 매개변수를 명시적으로 정의 할 수 있고, 다양한 옵션을 추가 할 수 있습니다.

 

Path와 Query는 Params 클래스의 서브 클래스입니다.

 

아래와 같이 main.py를 작성:

import uvicorn
from typing import List

from fastapi import FastAPI, Query, Path
from pydantic import BaseModel, parse_obj_as

app = FastAPI()

inventory = (
    {
        "id": 1,
        "user_id": 1,
        "name": "레전드포션",
        "price": 2500.0,
        "amount": 100,
    },
    {
        "id": 2,
        "user_id": 1,
        "name": "포션",
        "price": 300.0,
        "amount": 50,
    },
)


class Item(BaseModel):
    name: str
    price: float
    amount: int = 0


@app.get("/users/{user_id}/inventory", response_model=List[Item])
def get_item(
    user_id: int = Path(..., gt=0, title="사용자 id", description="DB의 user.id"),
    name: str = Query(None, min_length=1, max_length=2, title="아이템 이름"),
):
    user_items = []
    for item in inventory:
        if item["user_id"] == user_id:
            user_items.append(item)

    response = []
    for item in user_items:
        if name is None:
            response = user_items
            break
        if item["name"] == name:
            response.append(item)

    return response

if __name__ == '__main__':
	uvicorn.run("main:app", reload= True)

 

get_item 함수를 보면, user_id와 name을 명시적으로 받고 있는 걸 알 수 있습니다.

get_item 함수에 user_id에는 Path를 name에는 Query를 입력 받습니다. 

각 Path와 Query의 입력 값들을 살펴보면 다음과 같습니다.

 

  • Path
    • ...(ellipsis)은 생략라고해서 python에 있는 일종의 객체입니다.
    • pydantic에서의 ...은 필수 값이라는 의미이다.
    • gt = 0은 user_id는 0보다는 커야 된다라는 의미
    • title, description는 docs에서 어찌 보여줄지에 대한 옵션
  • Query
    • None이 존재, None의 경우 필수가 아니고, Optional이다. 라는 의미
    • min_length=1, 최소 길이가 1
    • max_length=2, 최대 길이가 2
    • title docs에서 어찌 보여줄지에 대한 옵션

그리고 아래 코드의 내용은 더미 데이터로 만든 inventory에서 user_id에 해당하는 item을 가져오기 위한 code입니다.

 

python으로 main.py를 실행하고, HTTPie를 사용해서 확인해보겠습니다.

$ http ':8000/users/1/inventory?name=포션'

 

영어뿐만 아니라 한글도 글자 갯수를 정확하게 측정합니다. 다음 두 가지만 주의하면 됩니다.

  • gt, ge, lt, le: 숫자
  • min_length, max_length: str
  • min_items, max_items: 컬렉션(e.g. List, Set)
뿐만 아니라 regex 옵션으로 정규표현식 검증도 가능합니다.