파이썬/Fast API

FastAPI 쿼리 매개변수

코샵 2025. 2. 9. 10:50
반응형

쿼리 매개변수는 FastAPI에서 데이터를 전달받는 핵심적인 방법 중 하나입니다. 다양한 데이터 타입을 어떻게 처리하는지 자세히 알아보겠습니다.

기본적인 쿼리 매개변수 사용

from fastapi import FastAPI, Query
from typing import Optional

app = FastAPI()

@app.get("/items/")
async def read_items(
    skip: Optional[int] = Query(default=0, ge=0),
    limit: int = Query(default=10, le=100),
    search: str = Query(default=None, min_length=3, max_length=50)
):
    return {
        "skip": skip,
        "limit": limit,
        "search": search
    }

날짜 데이터 처리하기

FastAPI에서는 datetime 객체를 직접 사용할 수 있습니다.

from fastapi import FastAPI, Query
from datetime import date, datetime
from typing import Optional

app = FastAPI()

@app.get("/events/")
async def get_events(
    start_date: date = Query(default=None),  # YYYY-MM-DD 형식
    end_date: date = Query(default=None),
    event_type: Optional[str] = None
):
    return {
        "start_date": start_date,
        "end_date": end_date,
        "event_type": event_type
    }

@app.get("/logs/")
async def get_logs(
    timestamp: datetime = Query(default=None)  # YYYY-MM-DD HH:MM:SS 형식
):
    return {"timestamp": timestamp}

복잡한 데이터 타입 처리

from enum import Enum
from pydantic import BaseModel, constr
from typing import List, Optional

class UserType(str, Enum):
    ADMIN = "admin"
    USER = "user"
    GUEST = "guest"

class DateRange(BaseModel):
    start_date: date
    end_date: date

@app.get("/users/")
async def get_users(
    user_type: UserType = Query(default=UserType.USER),
    age: Optional[int] = Query(default=None, ge=0, le=120),
    email: Optional[str] = Query(
        default=None,
        regex="^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$"
    ),
    tags: List[str] = Query(default=[])
):
    return {
        "user_type": user_type,
        "age": age,
        "email": email,
        "tags": tags
    }

커스텀 유효성 검사

from fastapi import Query, HTTPException
from datetime import date, timedelta

def validate_date_range(start_date: date, end_date: date):
    if start_date and end_date and start_date > end_date:
        raise HTTPException(
            status_code=400,
            detail="시작 날짜는 종료 날짜보다 이전이어야 합니다."
        )

@app.get("/reservations/")
async def get_reservations(
    start_date: date = Query(default=None),
    end_date: date = Query(default=None),
    room_type: Optional[str] = None
):
    if start_date and end_date:
        validate_date_range(start_date, end_date)

    # 최대 예약 기간 제한
    if start_date and end_date:
        date_diff = end_date - start_date
        if date_diff.days > 30:
            raise HTTPException(
                status_code=400,
                detail="예약 기간은 30일을 초과할 수 없습니다."
            )

    return {
        "start_date": start_date,
        "end_date": end_date,
        "room_type": room_type
    }

고급 쿼리 매개변수 예시

from typing import Union
from pydantic import BaseModel, constr

class FilterParams(BaseModel):
    search: Optional[str] = None
    category: Optional[str] = None
    min_price: Optional[float] = None
    max_price: Optional[float] = None
    date_from: Optional[date] = None
    date_to: Optional[date] = None

@app.get("/products/")
async def get_products(
    # 복잡한 필터링
    params: FilterParams = Depends(),

    # 정렬
    sort_by: str = Query(
        default="date",
        regex="^(date|price|name)$"
    ),
    order: str = Query(
        default="desc",
        regex="^(asc|desc)$"
    ),

    # 페이지네이션
    page: int = Query(default=1, ge=1),
    per_page: int = Query(default=10, ge=1, le=100)
):
    return {
        "filters": params.dict(),
        "sorting": {"sort_by": sort_by, "order": order},
        "pagination": {"page": page, "per_page": per_page}
    }

날짜 데이터 파싱 커스터마이징

from datetime import date
from typing import Optional
from fastapi import Query, HTTPException

def parse_date(date_str: str) -> date:
    try:
        return date.fromisoformat(date_str)
    except ValueError:
        raise HTTPException(
            status_code=400,
            detail="날짜 형식이 올바르지 않습니다. YYYY-MM-DD 형식을 사용하세요."
        )

@app.get("/custom-date/")
async def get_with_custom_date(
    target_date: str = Query(default=None)
):
    if target_date:
        parsed_date = parse_date(target_date)
        return {"parsed_date": parsed_date}
    return {"parsed_date": None}

이러한 방식으로 FastAPI에서 다양한 데이터 타입의 쿼리 매개변수를 처리할 수 있습니다. 특히 날짜 데이터는 ISO 형식(YYYY-MM-DD)을 기본적으로 지원하며, 필요한 경우 커스텀 파싱 로직을 추가할 수 있습니다.