Работа с формами несколько отличается от получения на сервере данных в теле запроса. Прежде всего необходимо установить модуль python-multipart с помощью команды
pip install python-multipart
Непосредственно в самом FastAPI для получения данных отправленных форм применяется класс fastapi.Form
Пусть у нас будет следующий проект:
В папке public определим файл index.html со следующим кодом:
<!DOCTYPE html> <html> <head> <title>METANIT.COM</title> <meta charset="utf-8" /> </head> <body> <h2>Форма ввода</h2> <form action="postdata" method="post"> <p> Name:<br> <input name="username" /> </p> <p> Age:<br> <input name="userage" type="number" /> </p> <input type="submit" value="Send" /> </form> </body> </html>
Здесь определена простейшая форма для ввода имени и возраста. И по нажатию на кнопку данные отправляются в запросе POST по адресу "postdata".
Для получения данных форм в файле main.py определим следующий код:
from fastapi import FastAPI, Form from fastapi.responses import FileResponse app = FastAPI() @app.get("/") def root(): return FileResponse("public/index.html") @app.post("/postdata") def postdata(username = Form(), userage=Form()): return {"name": username, "age": userage}
В функции postdata, которая обрабатывает запрос по одноименному пути, через параметры получаем отправленные данные. Причем параметры называются также, как и атрибуты name
у полей формы. А самим параметрам присваивается объект Form.
Класс Form из пакета fastapi
предоставляет возможности валидации значений форм с помощью некоторых параметров конструктора:
min_length: устанавливает минимальное количество символов в значении параметра
max_length: устанавливает максимальное количество символов в значении параметра
pattern: устанавливает регулярное выражение, которому должно соответствовать значение параметра
lt: значение параметра должно быть меньше определенного значения
le: значение параметра должно быть меньше или равно определенному значению
gt: значение параметра должно быть больше определенного значения
ge: значение параметра должно быть больше или равно определенному значению
Применим некотрые параметры:
from fastapi import FastAPI, Form from fastapi.responses import FileResponse app = FastAPI() @app.get("/") def root(): return FileResponse("public/index.html") @app.post("/postdata") def postdata(username: str = Form(min_length=2, max_length=20), userage: int =Form(ge=18, lt=111)): return {"name": username, "age": userage}
В данном случае параметр username
должен иметь не меньше 2 и не больше 20 символов, а параметр userage
должен представлять число в диапазоне от 18 (включительно) до 111 (не включая)
С помощью параметра default
конструктора Form можно установить значение по умолчанию на случай, если во входящих данных отсуствуют соответствующие значения:
from fastapi import FastAPI, Form from fastapi.responses import FileResponse app = FastAPI() @app.get("/") def root(): return FileResponse("public/index.html") @app.post("/postdata") def postdata(username: str = Form(default ="Undefined", min_length=2, max_length=20), userage: int =Form(default=18, ge=18, lt=111)): return {"name": username, "age": userage}
С помощью форм могут отправляться наборы данных. Например, изменим файл index.html следующим образом:
<!DOCTYPE html> <html> <head> <title>METANIT.COM</title> <meta charset="utf-8" /> </head> <body> <h2>Форма ввода</h2> <form action="postdata" method="post"> <p> Name:<br> <input name="username" /> </p> <p> Languages:<br> <input name="languages" /><br><br> <input name="languages" /><br><br> <input name="languages" /><br><br> </p> <input type="submit" value="Send" /> </form> </body> </html>
Здесь на форме определен набор элементов ввода, которые имеют одно и то же имя - "languages". При отправке формы из значений этих элементов будет формироваться набор. Для получения этого набора в коде сервера определим соответствующий параметр как параметр типа list:
from fastapi import FastAPI, Form from fastapi.responses import FileResponse app = FastAPI() @app.get("/") def root(): return FileResponse("public/index.html") @app.post("/postdata") def postdata(username: str = Form(), languages: list =Form()): return {"name": username, "languages": languages}
Единственное неудобство, с которым в данном случае можно столкнуться, это оправка пустых строк, как в скриншоте ниже в случае с третьим полев ввода языка: