Query-параметры¶
Когда вы объявляете параметры функции, которые не являются параметрами пути, они автоматически интерпретируются как "query"-параметры.
from fastapi import FastAPI
app = FastAPI()
fake_items_db = [{"item_name": "Foo"}, {"item_name": "Bar"}, {"item_name": "Baz"}]
@app.get("/items/")
async def read_item(skip: int = 0, limit: int = 10):
return fake_items_db[skip : skip + limit]
Query-параметры представляют из себя набор пар ключ-значение, которые идут после знака ?
в URL-адресе, разделенные символами &
.
Например, в этом URL-адресе:
http://127.0.0.1:8000/items/?skip=0&limit=10
...параметры запроса такие:
skip
: со значением0
limit
: со значением10
Будучи частью URL-адреса, они "по умолчанию" являются строками.
Но когда вы объявляете их с использованием аннотаций (в примере выше, как int
), они конвертируются в указанный тип данных и проходят проверку на соответствие ему.
Все те же правила, которые применяются к path-параметрам, также применяются и query-параметрам:
- Поддержка от редактора кода (очевидно)
- "Парсинг" данных
- Проверка на соответствие данных (Валидация)
- Автоматическая документация
Значения по умолчанию¶
Поскольку query-параметры не являются фиксированной частью пути, они могут быть не обязательными и иметь значения по умолчанию.
В примере выше значения по умолчанию равны skip=0
и limit=10
.
Таким образом, результат перехода по URL-адресу:
http://127.0.0.1:8000/items/
будет таким же, как если перейти используя параметры по умолчанию:
http://127.0.0.1:8000/items/?skip=0&limit=10
Но если вы введёте, например:
http://127.0.0.1:8000/items/?skip=20
Значения параметров в вашей функции будут:
skip=20
: потому что вы установили это в URL-адресеlimit=10
: т.к это было значение по умолчанию
Необязательные параметры¶
Аналогично, вы можете объявлять необязательные query-параметры, установив их значение по умолчанию, равное None
:
from fastapi import FastAPI
app = FastAPI()
@app.get("/items/{item_id}")
async def read_item(item_id: str, q: str | None = None):
if q:
return {"item_id": item_id, "q": q}
return {"item_id": item_id}
🤓 Other versions and variants
from typing import Union
from fastapi import FastAPI
app = FastAPI()
@app.get("/items/{item_id}")
async def read_item(item_id: str, q: Union[str, None] = None):
if q:
return {"item_id": item_id, "q": q}
return {"item_id": item_id}
В этом случае, параметр q
будет не обязательным и будет иметь значение None
по умолчанию.
Важно
Также обратите внимание, что FastAPI достаточно умён чтобы заметить, что параметр item_id
является path-параметром, а q
нет, поэтому, это параметр запроса.
Преобразование типа параметра запроса¶
Вы также можете объявлять параметры с типом bool
, которые будут преобразованы соответственно:
from fastapi import FastAPI
app = FastAPI()
@app.get("/items/{item_id}")
async def read_item(item_id: str, q: str | None = None, short: bool = False):
item = {"item_id": item_id}
if q:
item.update({"q": q})
if not short:
item.update(
{"description": "This is an amazing item that has a long description"}
)
return item
🤓 Other versions and variants
from typing import Union
from fastapi import FastAPI
app = FastAPI()
@app.get("/items/{item_id}")
async def read_item(item_id: str, q: Union[str, None] = None, short: bool = False):
item = {"item_id": item_id}
if q:
item.update({"q": q})
if not short:
item.update(
{"description": "This is an amazing item that has a long description"}
)
return item
В этом случае, если вы сделаете запрос:
http://127.0.0.1:8000/items/foo?short=1
или
http://127.0.0.1:8000/items/foo?short=True
или
http://127.0.0.1:8000/items/foo?short=true
или
http://127.0.0.1:8000/items/foo?short=on
или
http://127.0.0.1:8000/items/foo?short=yes
или в любом другом варианте написания (в верхнем регистре, с заглавной буквой, и т.п), внутри вашей функции параметр short
будет иметь значение True
типа данных bool
. В противном случае - False
.
Смешивание query-параметров и path-параметров¶
Вы можете объявлять несколько query-параметров и path-параметров одновременно,FastAPI сам разберётся, что чем является.
И вы не обязаны объявлять их в каком-либо определенном порядке.
Они будут обнаружены по именам:
from fastapi import FastAPI
app = FastAPI()
@app.get("/users/{user_id}/items/{item_id}")
async def read_user_item(
user_id: int, item_id: str, q: str | None = None, short: bool = False
):
item = {"item_id": item_id, "owner_id": user_id}
if q:
item.update({"q": q})
if not short:
item.update(
{"description": "This is an amazing item that has a long description"}
)
return item
🤓 Other versions and variants
from typing import Union
from fastapi import FastAPI
app = FastAPI()
@app.get("/users/{user_id}/items/{item_id}")
async def read_user_item(
user_id: int, item_id: str, q: Union[str, None] = None, short: bool = False
):
item = {"item_id": item_id, "owner_id": user_id}
if q:
item.update({"q": q})
if not short:
item.update(
{"description": "This is an amazing item that has a long description"}
)
return item
Обязательные query-параметры¶
Когда вы объявляете значение по умолчанию для параметра, который не является path-параметром (в этом разделе, мы пока что познакомились только с path-параметрами), то это значение не является обязательным.
Если вы не хотите задавать конкретное значение, но хотите сделать параметр необязательным, вы можете установить значение по умолчанию равным None
.
Но если вы хотите сделать query-параметр обязательным, вы можете просто не указывать значение по умолчанию:
from fastapi import FastAPI
app = FastAPI()
@app.get("/items/{item_id}")
async def read_user_item(item_id: str, needy: str):
item = {"item_id": item_id, "needy": needy}
return item
Здесь параметр запроса needy
является обязательным параметром с типом данных str
.
Если вы откроете в браузере URL-адрес, например:
http://127.0.0.1:8000/items/foo-item
...без добавления обязательного параметра needy
, вы увидите подобного рода ошибку:
{
"detail": [
{
"loc": [
"query",
"needy"
],
"msg": "field required",
"type": "value_error.missing"
}
]
}
Поскольку needy
является обязательным параметром, вам необходимо указать его в URL-адресе:
http://127.0.0.1:8000/items/foo-item?needy=sooooneedy
...это будет работать:
{
"item_id": "foo-item",
"needy": "sooooneedy"
}
Конечно, вы можете определить некоторые параметры как обязательные, некоторые - со значением по умполчанию, а некоторые - полностью необязательные:
from fastapi import FastAPI
app = FastAPI()
@app.get("/items/{item_id}")
async def read_user_item(
item_id: str, needy: str, skip: int = 0, limit: int | None = None
):
item = {"item_id": item_id, "needy": needy, "skip": skip, "limit": limit}
return item
🤓 Other versions and variants
from typing import Union
from fastapi import FastAPI
app = FastAPI()
@app.get("/items/{item_id}")
async def read_user_item(
item_id: str, needy: str, skip: int = 0, limit: Union[int, None] = None
):
item = {"item_id": item_id, "needy": needy, "skip": skip, "limit": limit}
return item
В этом примере, у нас есть 3 параметра запроса:
needy
, обязательныйstr
.skip
, типаint
и со значением по умолчанию0
.limit
, необязательныйint
.
Подсказка
Вы можете использовать класс Enum
также, как ранее применяли его с Path-параметрами.