Путь запроса может содержать специальные значения, которые фреймворк 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 цифр.