В запросе могут передаваться различные данных, например, через отправку каких-то значений в формате json. Рассмотрим, как получать подобные данные.
Для получения данных из тела запроса можно использовать класс Body из пакета fastapi
. Данный класс позволяет связать с параметром функции-обработчика запроса либо все тело запроса,
либо какие-то отдельные его значения. Для примера для упрощения отправки данных определим в проекте папку public, в которой создадим новый файл
index.html со следующим кодом:
<!DOCTYPE html> <html> <head> <title>METANIT.COM</title> <meta charset="utf-8" /> </head> <body> <div id="message"></div> <p> Введите имя: <br /> <input name="username" id="username" /> </p> <p> Введите возраст: <br /> <input name="userage" id="userage" type="number" /> </p> <button onclick="send()">Отправить</button> <script> async function send(){ // получаем введеное в поле имя и возраст const username = document.getElementById("username").value; const userage = document.getElementById("userage").value; // отправляем запрос const response = await fetch("/hello", { method: "POST", headers: { "Accept": "application/json", "Content-Type": "application/json" }, body: JSON.stringify({ name: username, age: userage }) }); if (response.ok) { const data = await response.json(); document.getElementById("message").textContent = data.message; } else console.log(response); } </script> </body> </html>
В данном случае для ввода данных на веб-странице определено текстовое поле, в которое пользователь вводит свое имя. По нажатию на кнопку срабатывает функция send()
,
определенная в коде javascript. Эта функция получает введенное значение и с помощью функции fetch отправляет его по адресу "/hello" в запросе типа POST. При этом в теле запроса посылаются
сериализованные в JSON данные. В частности, посылается объект, в котором свойство name хранит введенное имя.
После отправки запроса мы ожидаем, что сервер в ответ пришлет нам некоторые данные - некоторый объект JSON, в котором будет свойство "message". И значение этого свойства выводим на веб-страницу в элемент с id=message.
Затем определим основной файл приложения main.py, который будет получать и обрабатывать запросы:
from fastapi import FastAPI, Body from fastapi.responses import FileResponse app = FastAPI() @app.get("/") def root(): return FileResponse("public/index.html") @app.post("/hello") #def hello(name = Body(embed=True)): def hello(data = Body()): name = data["name"] age = data["age"] return {"message": f"{name}, ваш возраст - {age}"}
Здесь при обращении по пути "/" клиенту будет отправляться страница index.html для ввода данных.
Для обработки полученных в POST-запросе данных по адресу "/hello" определена функция hello()
. Эта функция имеет один параметр - data, который получает содержимое тела запроса:
data = Body()
То есть здесь data
будет представлять весь объект, который отправляется с веб-страницы и который имеет свойства "name" и "age". Этот объект в python будет представлять словарь.
Соответственно, чтобы получить значения свойства "name", обращаемся по одноименному ключу:
name = data["name"]
Подобным образом получаем значение свойства "age". Затем в ответ клиенту посылается словарь с элементом "message".
В примере выше мы получали все данные из тела запроса в один параметр. Однако, установив параметр embed=True
, можно получать отдельные значения:
from fastapi import FastAPI, Body from fastapi.responses import FileResponse app = FastAPI() @app.get("/") def root(): return FileResponse("public/index.html") @app.post("/hello") def hello(name = Body(embed=True), age = Body(embed=True)): return {"message": f"{name}, ваш возраст - {age}"}
Класс Body позволяет валидировать значения из тела запроса. В частности, через конструктор Body можно установить следующие параметры для валидации значений:
min_length: устанавливает минимальное количество символов в значении параметра
max_length: устанавливает максимальное количество символов в значении параметра
pattern: устанавливает регулярное выражение, которому должно соответствовать значение параметра
lt: значение параметра должно быть меньше определенного значения
le: значение параметра должно быть меньше или равно определенному значению
gt: значение параметра должно быть больше определенного значения
ge: значение параметра должно быть больше или равно определенному значению
Применим некотрые параметры:
from fastapi import FastAPI, Body from fastapi.responses import FileResponse app = FastAPI() @app.get("/") def root(): return FileResponse("public/index.html") @app.post("/hello") def hello(name:str = Body(embed=True, min_length=3, max_length=20), age: int = Body(embed=True, ge=18, lt=111)): return {"message": f"{name}, ваш возраст - {age}"}
В данном случае значение параметра name
должно иметь не меньше 3 и не больше 20 символов, а параметр "age" должен представлять число в диапазоне от 18 (включительно) до 111 (не включая)