Programming Language/Python

[FastAPI] 5. Query Parameters(Annotated, Query)

LeeJaeJun 2024. 6. 19. 18:28
728x90
반응형

Annotated와 Query

from typing import Annotated

from fastapi import FastAPI, Query

app = FastAPI()


@app.get("/items/")
async def read_items(q: Annotated[str | None, Query(max_length=50)] = None):
    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    if q:
        results.update({"q": q})
    return results
  • Annotated는 typing에서 Query는 fastapi에서 Import 가능 (Python 3.9 이상 기준)
  • Annotated의 목적은 파라미터 타입에 추가적인 조건과 메타데이터를 제공하여 더 세세한 타입 검사와 유효성 검사를 수행하는 것
    • FastAPI는 Annotated 안의 내용을 바탕으로 query parameter 유효성 검사
    • q: str | None = None을 Annotated를 통해 나타내면 Annotated[str | None] = None
    • 주로 타입 힌트와 메타데이터의 결합을 위해 사용
  • Query는 FastAPI에서 쿼리 매개변수의 유효성 검사를 설정하는 데 사용
    • 기본값을 지정하고, 최소 및 최대 길이, 정규 표현식 등을 설정
    • Query(max_length=50)은 q 파라미터 길이를 50으로 제한
    • Annotated를 안쓰고q: str = Query(None, max_length=50) 이렇게 설정해도 가능 
    • Annotated[str | None, Query(min_length=3, max_length=50, pattern="^yourpattern$")] = None
      • 정규표현식도 사용 가능. 위의 예시는 q가 "yourpattern"라는 문자열과 정확히 일치해야 한다는 정규표현식 사용
      • ^: 문자열의 시작
      • $: 문자열의 끝
    • 이외에도 title, description, alias, deprecated 등 사용 가능
    • Numeric과 관련된 parameter들도 존재
      • gt: greater than
      • ge: greater than or equal
      • lt: less than
      • le: less than or equal
  • Annotated 안에 Query를 쓸 때는 Query 안에 default 값을 지정할 수 없음
    • q: Annotated[str, Query(default="rick")] = "morty" -> 허용 x(default가 rick인지, morty인지 모호)
    • q: Annotated[str, Query()] = "rick" -> Annotated를 사용할 때 초기화 방법
    • q: str = Query(default="rick") -> Query만 사용할 때 초기화 방법
  • 기본값을 None으로 하고싶지 않은데, required parameter로 설정하고 싶은 경우 Ellipsis(...) 사용
from fastapi import FastAPI, Query
from typing_extensions import Annotated

app = FastAPI()

@app.get("/items/")
async def read_items(q: Annotated[str, Query(min_length=3)] = ...):
    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    if q:
        results.update({"q": q})
    return results
  • 기본값이 None이 아니더라도 None을 허용하며 required parameter로 설정하고 싶은경우
    • read_items(q: Annotated[str | None, Query(min_length=3) = ...)
from typing import Annotated

from fastapi import FastAPI, Query

app = FastAPI()


@app.get("/items/")
async def read_items(q: Annotated[list[str] | None, Query()] = None):
    query_items = {"q": q}
    return query_items
  • 입력값으로 list나 multiple values로 받고 싶은 경우
  • list[str] 대신 그냥 list라고 해도 q 파라미터는 문자열 리스트로 전달 가능
    • q: Annotated[list, Query()] = None
  • default 값을 설정하고 싶을 때
    • read_items(q: Annotated[list[str], Query()] = ["foo", "bar"]
    • 위 경우에는 deafult 값이 ["foo", "bar"]이라는 문자열 리스트가 됨 

 

Annotated랑 같이 사용하는 것을 권장하는 이유

  • 직관적: 함수 매개변수의 기본값이 실제 기본값으로 더 직관적
  • 호환성: FastAPI 없이 다른 곳에서 호출해도 예상대로 작동. 필수 매개변수가 없으면 편집기와 Python이 오류를 알림
    • Annotated를 사용하지 않고 기본값을 설정하면 FastAPI 없이 다른 곳에서 해당 함수를 호출할 때, 함수가 예상대로 작동하려면 반드시 인수를 전달해야 함
    • 그렇지 않으면 함수가 잘 작동하지 않거나 값이 예상과 다를 수 있음.(함수 호출 시 기본값이 잘못 설정될 수 있음)
def read_items(q: str = Query(None, max_length=50)):

Annotated로 초기화 하지 않고 그냥 Query로 초기화 한 경우, 위 함수를 FastAPI 없이 호출하면 q가 Query 객체로 설정되어 예상과 다른 결과를 초래할 수 있음(FastAPI 상에서는 str)

def read_items(q: Annotated[str, Query()] = "default_value"):

Annotated로 초기화한 경우에는 FastAPI로 호출하지 않더라도 q가 str로 올바르게 설정(비어있는 경우 default값으로)

  • 다중 메타데이터: Annotated는 여러 메타데이터 주석을 가질 수 있어 Typer와 같은 도구와 함께 사용 가능

https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#__tabbed_16_1

 

Query Parameters and String Validations - FastAPI

FastAPI framework, high performance, easy to learn, fast to code, ready for production

fastapi.tiangolo.com

 

 

 

 

728x90
반응형