쿼리 매개변수는 API의 경로가 아닌, URL의 ? 뒤에 위치하며, FastAPI는 이를 쉽게 처리할 수 있습니다. Query 클래스를 사용하면 쿼리 매개변수에 대한 검증과 추가 정보를 선언할 수 있습니다.
쿼리 매개변수는 선택적이거나 필수적일 수 있으며, 기본값을 설정할 수도 있습니다.
from typing import Union
from fastapi import FastAPI
app = FastAPI()
@app.get("/items/")
async def read_items(q: Union[str, None] = None):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
q는 Optional[str]로 선언되어 있으며, 기본값은 None입니다.http://127.0.0.1:8000/items/?q=searchq는 선택적이며, 값이 없으면 None으로 처리됩니다.쿼리 매개변수에 추가적인 검증을 선언하려면 Query 클래스를 사용합니다. 이를 통해 문자열의 길이 제한, 정규표현식, 기본값 등을 설정할 수 있습니다.
from fastapi import FastAPI, Query
from typing import Union
app = FastAPI()
@app.get("/items/")
async def read_items(q: Union[str, None] = Query(default=None, max_length=50)):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
max_length=50: q의 길이를 50자 이하로 제한합니다. http://127.0.0.1:8000/items/?q=verylongstring으로 50자를 넘는 값을 입력하면 ValidationError가 발생합니다.@app.get("/items/")
async def read_items(
q: Union[str, None] = Query(default=None, min_length=3, max_length=50),
):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
q는 최소 3자 이상이어야 합니다.q는 최대 50자까지 입력할 수 있습니다.정규표현식을 사용하여 쿼리 매개변수의 값이 특정 패턴과 일치하는지 검증할 수 있습니다.
@app.get("/items/")
async def read_items(
q: Union[str, None] = Query(default=None, min_length=3, max_length=50, pattern="^fixedquery$"),
):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
q 값이 정확히 "fixedquery"와 일치해야 합니다.^: 문자열의 시작.$: 문자열의 끝.http://127.0.0.1:8000/items/?q=fixedquery로 호출하면 성공, 다른 값은 검증 오류 발생.기본값을 설정하면 쿼리 매개변수가 제공되지 않을 때 해당 기본값이 사용됩니다.
@app.get("/items/")
async def read_items(q: str = Query(default="fixedquery", min_length=3)):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
"fixedquery": 쿼리 매개변수가 없을 때 기본적으로 이 값을 사용합니다.http://127.0.0.1:8000/items/로 호출하면 q="fixedquery"가 사용됩니다.쿼리 매개변수를 필수로 만들려면 ...를 사용합니다. 이는 파이썬의 Ellipsis로, 기본값이 없다는 의미로 사용됩니다.
@app.get("/items/")
async def read_items(q: str = Query(..., min_length=3)):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
q는 필수로 선언되며, 기본값이 없습니다.쿼리 매개변수를 리스트로 받을 수도 있습니다. Query를 명시적으로 사용하여 여러 값을 처리합니다.
from typing import List, Union
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/items/")
async def read_items(q: Union[List[str], None] = Query(default=None)):
return {"q": q}
http://127.0.0.1:8000/items/?q=foo&q=bar{
"q": ["foo", "bar"]
}
쿼리 매개변수에 대한 추가 정보를 선언할 수 있습니다. 이러한 정보는 OpenAPI 스키마에 포함되어 문서화됩니다.
@app.get("/items/")
async def read_items(
q: Union[str, None] = Query(
default=None,
title="Query string",
description="Query string for the items to search in the database.",
min_length=3,
),
):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
파이썬 변수로 사용할 수 없는 이름을 쿼리 매개변수로 사용할 경우 alias를 사용하여 다른 이름으로 처리할 수 있습니다.
@app.get("/items/")
async def read_items(q: Union[str, None] = Query(default=None, alias="item-query")):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
alias="item-query": item-query라는 쿼리 매개변수를 사용할 수 있습니다.http://127.0.0.1:8000/items/?item-query=foobar사용하지 않는 쿼리 매개변수를 표시하려면 deprecated=True를 설정할 수 있습니다.
@app.get("/items/")
async def read_items(
q: Union[str, None] = Query(
default=None,
alias="item-query",
deprecated=True,
min_length=3,
max_length=50
),
):
results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
if q:
results.update({"q": q})
return results
하여 쿼리 매개변수에 대해 추가 검증 및 메타데이터를 정의할 수 있습니다.
FastAPI에서는 경로 매개변수에 대한 검증을 Path 클래스를 사용하여 설정할 수 있습니다. 이를 통해 경로 매개변수에 숫자 범위와 같은 제약을 추가하고, 메타데이터를 선언할 수 있습니다.
경로 매개변수에 검증을 추가하기 위해 Path 클래스를 임포트합니다.
from fastapi import FastAPI, Path
from typing import Union
app = FastAPI()
@app.get("/items/{item_id}")
async def read_items(
item_id: int = Path(title="The ID of the item to get"),
q: Union[str, None] = None,
):
results = {"item_id": item_id}
if q:
results.update({"q": q})
return results
int 타입입니다.경로 매개변수는 경로 자체의 일부이기 때문에 항상 필수적입니다. 기본값을 설정하거나 None으로 선언해도 필수로 간주됩니다.
@app.get("/items/{item_id}")
async def read_items(
item_id: int = Path(title="The ID of the item to get"),
q: Union[str, None] = None,
):
return {"item_id": item_id}
Path 클래스를 사용하여 경로 매개변수에 대한 숫자 검증을 설정할 수 있습니다.
숫자 매개변수에 대해 다음과 같은 검증을 사용할 수 있습니다:
@app.get("/items/{item_id}")
async def read_items(
item_id: int = Path(title="The ID of the item to get", ge=1, le=1000),
q: Union[str, None] = None,
):
return {"item_id": item_id}
http://127.0.0.1:8000/items/5는 유효한 값.http://127.0.0.1:8000/items/0는 ValidationError 발생.숫자 검증을 적용한 경로 매개변수와 쿼리 매개변수를 함께 사용할 수 있습니다.
from fastapi import FastAPI, Path, Query
from typing import Union
app = FastAPI()
@app.get("/items/{item_id}")
async def read_items(
item_id: int = Path(title="The ID of the item to get", ge=1, le=1000),
q: Union[str, None] = Query(default=None),
):
results = {"item_id": item_id}
if q:
results.update({"q": q})
return results
숫자 검증은 float 값에 대해서도 동작합니다.
@app.get("/items/{item_id}")
async def read_items(
item_id: int = Path(title="The ID of the item to get", ge=1, le=1000),
size: float = Query(gt=0, lt=10.5),
):
return {"item_id": item_id, "size": size}
http://127.0.0.1:8000/items/10?size=5.5는 유효.http://127.0.0.1:8000/items/10?size=11는 ValidationError 발생.경로 매개변수는 항상 필수적이기 때문에, 기본값이 있는 쿼리 매개변수 앞에 필수 경로 매개변수를 배치해야 할 때가 있습니다. 하지만 매개변수를 재정렬해 경로 매개변수를 앞으로 배치할 수 있습니다.
@app.get("/items/{item_id}")
async def read_items(
q: str, item_id: int = Path(title="The ID of the item to get", ge=1),
):
return {"item_id": item_id, "q": q}
q는 필수적인 쿼리 매개변수입니다.경로 매개변수를 *로 표시해 매개변수의 순서를 명확하게 정의할 수 있습니다.
@app.get("/items/{item_id}")
async def read_items(
*, item_id: int = Path(title="The ID of the item to get", ge=1), q: str
):
return {"item_id": item_id, "q": q}
*는 이후의 매개변수가 키워드 인자(키-값 쌍)로 전달됨을 의미합니다.ge=1 제약이 있으며, q는 필수적인 쿼리 매개변수입니다.ge, gt, le, lt 등을 통해 숫자 범위를 제한할 수 있습니다.*)를 사용해 매개변수를 명확하게 정렬할 수 있습니다.FastAPI에서는 여러 쿼리 매개변수가 관련된 경우, Pydantic 모델을 사용하여 이들을 하나의 그룹으로 선언할 수 있습니다. 이를 통해 여러 곳에서 모델을 재사용하거나, 한 번에 검증 및 메타데이터를 선언할 수 있습니다. 😎
Pydantic 모델을 이용하여 쿼리 매개변수를 선언할 수 있습니다. 예를 들어, 필터링이나 정렬 같은 여러 매개변수가 필요할 때 Pydantic 모델로 쉽게 관리할 수 있습니다.
from typing import Annotated, Literal
from fastapi import FastAPI, Query
from pydantic import BaseModel, Field
app = FastAPI()
class FilterParams(BaseModel):
limit: int = Field(100, gt=0, le=100)
offset: int = Field(0, ge=0)
order_by: Literal["created_at", "updated_at"] = "created_at"
tags: list[str] = []
@app.get("/items/")
async def read_items(filter_query: Annotated[FilterParams, Query()]):
return filter_query
created_at 또는 updated_at으로 정렬할 수 있습니다.FastAPI는 쿼리 매개변수를 추출해 Pydantic 모델의 필드로 매핑합니다.
/docs에서 API 문서 UI를 확인할 수 있으며, 모델로 정의된 쿼리 매개변수들이 자동으로 문서화됩니다.특정 경우에는 쿼리 매개변수에 대해 추가적인 매개변수를 허용하지 않도록 제한할 수 있습니다. 이를 위해 Pydantic의 model_config 설정을 사용합니다.
from typing import Annotated, Literal
from fastapi import FastAPI, Query
from pydantic import BaseModel, Field
app = FastAPI()
class FilterParams(BaseModel):
model_config = {"extra": "forbid"}
limit: int = Field(100, gt=0, le=100)
offset: int = Field(0, ge=0)
order_by: Literal["created_at", "updated_at"] = "created_at"
tags: list[str] = []
@app.get("/items/")
async def read_items(filter_query: Annotated[FilterParams, Query()]):
return filter_query
클라이언트가 정의되지 않은 매개변수를 보내면 오류 응답을 받게 됩니다.
https://example.com/items/?limit=10&tool=plumbus{
"detail": [
{
"type": "extra_forbidden",
"loc": ["query", "tool"],
"msg": "Extra inputs are not permitted",
"input": "plumbus"
}
]
}