Путь запроса может содержать специальные значения, которые фреймворк FastAPI может связать с параметрыми функции обработчика запроса. Это так называемые параметры пути (path parameter). Благодаря параметрам пути можно передавать в приложения некоторые значения.
Параметры пути определяются в шаблоне пути внутри фигурных скобок: {название_параметра}. Например, определим следующее приложение:
from fastapi import FastAPI
app = FastAPI()
@app.get("/users/{id}")
def users(id):
return {"user_id": id}
в данном случае декоратор app.get использует шаблон пути "/users/{id}". Здесь id представляет параметр пути.
Функция users(), которая обрабатывает запрос по этому пути, принимает одноименный параметр. Через этот параметр в функцию будет передаваться значения из пути,
которое фреймворк определит как параметр id.
Так, на скриншоте видно, что браузер отправляет запрос по адресу http://127.0.0.1:8000/users/315, то есть путь запроса в данном случае представляет
users/315. Фреймворк FastAPI видит, что этот путь соответствует шаблону "/users/{id}", поэтому данный запрос будет обрабатываться функцией users.
Параметр id в шаблоне пути составляет второй сегмент адреса. Соответственно фреймворк сможет сопоставть сегмент "315" с параметром id. Поэтому при обращении по адресу http://127.0.0.1:8000/users/315
параметр id в функции users получит значение 315.
Подобным образом можно использовать и большее количество параметров:
from fastapi import FastAPI
app = FastAPI()
@app.get("/users/{name}/{age}")
def users(name, age):
return {"user_name": name, "user_age": age}
В данном случае функция users обрабатывает запросы, путь которых соответствует шаблону "/users/{name}/{age}". Подобный путь должен состоять из трех сегментов, где второй сегмент представляет значение параметра name, а третий сегмент - значение параметра age.
Обычно если в пути передается несколько параметров, то разделителем между ними, как правило, служит слеш, который закрывает сегмент, как в примере выше. Однако это необязательно, например, мы можем разделить параметры с помощью дефиса:
@app.get("/users/{name}-{age}")
def users(name, age):
return {"user_name": name, "user_age": age}
Такому шаблону соответствовал бы запрос по пути http://127.0.0.1:8000/users/Tom-38, и фреймворк FastAPI автоматически распарсил бы запрошенный путь и разделил бы его последний сегмент
на параметры name и age.
Однако при определении шаблонов путей следует учитывать, что между различными шаблонами может возникнуть двойственность, когда запрос соответствует нескольким определенным шаблонам. И в этой связи следует учитывать очередность определения шаблонов путей. Например:
from fastapi import FastAPI
app = FastAPI()
@app.get("/users/{name}")
def users(name):
return {"user_name": name}
@app.get("/users/admin")
def admin():
return {"message": "Hello admin"}
В данном случае мы хотим, чтобы запросы по пути "/users/admin" обрабатывала функция admin(). А остальные пути по шаблону "/users/{name}", где второй сегмент представляет параметр name,
обрабатывала бы функция users(). Однако если мы обратимся к приложению с запросом http://127.0.0.1:8000/users/admin, то мы увидим, что запрос
обрабатывает функция users(), а не admin():
Потому что функция users определена до функции admin, соответственно функция users и будет обрабатывать данный запрос. Чтобы добиться нужного результата, нам надо поменять определение функций местами:
from fastapi import FastAPI
app = FastAPI()
@app.get("/users/admin")
def admin():
return {"message": "Hello admin"}
@app.get("/users/{name}")
def users(name):
return {"user_name": name}
FastAPI позволяет ограничить тип параметров и соответственно набор используемых значений. Например, мы хотим, чтобы параметр id представлял только целое число:
from fastapi import FastAPI
app = FastAPI()
@app.get("/users/{id}")
def users(id: int):
return {"user_id": id}
Чтобы указать, что параметр - целое число, у параметра функции явным образом задается тип int. И если мы попробуем передать этому параметру не целочисленное значение, то сервер отправит сообщение об ошибке:
Подобным образом в качестве ограничения можно использовать и другие типы: str, float, bool и ряд других.
Дополнительно для работы с параметрами пути фреймворк FastAPI предоставляет класс Path из пакета fastapi. Класс Path позволяет валидировать
значения параметров. В частности, через конструктор Path можно установить следующие параметры для валидации значений:
min_length: устанавливает минимальное количество символов в значении параметра
max_length: устанавливает максимальное количество символов в значении параметра
pattern: устанавливает регулярное выражение, которому должно соответствовать значение параметра
lt: значение параметра должно быть меньше определенного значения
le: значение параметра должно быть меньше или равно определенному значению
gt: значение параметра должно быть больше определенного значения
ge: значение параметра должно быть больше или равно определенному значению
Применим некотрые параметры:
from fastapi import FastAPI, Path
app = FastAPI()
@app.get("/users/{name}")
def users(name:str = Path(min_length=3, max_length=20)):
return {"name": name}
В данном случае получаем параметр name. Причем его значение должно иметь не меньше 3 и не больше 20 символов.
Подобным образом можно использовать другие параметры валидации:
from fastapi import FastAPI, Path
app = FastAPI()
@app.get("/users/{name}/{age}")
def users(name:str = Path(min_length=3, max_length=20),
age: int = Path(ge=18, lt=111)):
return {"name": name, "age": age}
В данном случае добавляется параметр "age", который должен представлять число в диапазоне от 18 (включительно) до 111 (не включая)
Валидация с помощью регулярного значения:
from fastapi import FastAPI, Path
app = FastAPI()
@app.get("/users/{phone}")
def users(phone:str = Path(pattern=r"^\d{11}$")):
return {"phone": phone}
Здесь параметр phone должен состоять из 11 цифр.