Раздел помощи SpaceWeb

Обработка данных входящих запросов в Flask

22 фев, 2024

Что такое Flask

Flask – это микрофреймворк для создания веб-приложений на языке программирования Python. Он был создан, чтобы облегчить разработку веб-приложений. 

У Flask нет жестких структур и правил, что позволяет разработчикам выбирать инструменты и библиотеки по своему усмотрению. 

Что такое фреймворк

Фреймворк – это комплекс программных и аппаратных средств, которые предназначены для разработки и обеспечения функционирования компьютерных программ. Сюда входят средства разработки, библиотеки, стандарты программирования и так далее. 

Фреймворк предоставляет основные структуры для разработки приложений, определяя архитектурные принципы, потоки данных и обработки событий. Это позволяет разработчикам фокусироваться на более специфических задачах, не связанных с общими аспектами приложения.

Предварительные требования

  1. Для тестирования конечных точек API необходимо установить Postman или использовать альтернативный инструмент с аналогичными возможностями.
  2. Для успешного выполнения данного руководства необходимо установить Python в вашей локальной среде.
  3. Мы рекомендуем использовать инструмент Pipenv, который объединяет в себе функционал Pipfile, pip и virtualenv 

Настройка проекта

Чтобы показать вам различные методы использования запросов, мы создадим приложение на основе Flask.

  1. Прежде всего, необходимо создать каталог для проекта. Пропишите следующую команду:

mkdir flask_request_example

  1. Затем перейдите в новый каталог:

cd flask_request_example

  1. Установите Flask, выполнив:

pipenv install Flask

Команда «pipenv» создаст виртуальное окружение для проекта, а файл Pipfile установит Flask и создаст файл Pipfile.lock.

  1. Активируйте виртуальное окружение для этого проекта:

pipenv shell

  1. Для обращения к входящим данным в Flask используйте объект «request». В нем содержатся все данные запроса, такие как MIME-тип, источник, IP-адрес, необработанные данные, метод HTTP, заголовки и другие.
  2. Для доступа к объекту «request» в Flask вам нужно импортировать его из библиотеки Flask

from flask import request

После этого вы сможете использовать его в любых функциях представлений.

  1. Используйте редактор кода для создания файла «yourapp.py».
  2. Импортируйте Flask и объект «request», а также установите маршруты для «query-example», «form-example» и «json-example»:

  1. Затем запустите приложение в терминале с помощью следующей команды:

python yourapp.py

Приложение будет доступно по адресу http://127.0.0.1:5000. Вы сможете открыть каждый маршрут в браузере:

http://127.0.0.1:5000/query-example ИЛИ localhost:5000/query-example

http://127.0.0.1:5000/form-example ИЛИ localhost:5000/form-example

http://127.0.0.1:5000/json-example ИЛИ localhost:5000/json-example

Код определяет три маршрута, и при открытии каждого из них вы увидите соответствующие сообщения: «Пример строки запроса», «Пример данных формы» и «Пример объекта JSON».

Использование аргументов запроса

Аргументы URL, которые добавляются в строку запроса, часто применяются для передачи данных в веб-приложение. Вероятно, вы уже встречали строки запроса на веб-страницах.

Форма строки запроса выглядит следующим образом:

example.ru?arg1=value1&arg2=value2

Эта строка начинается после знака вопроса (?). В ней содержатся пары ключ-значение, разделенные символом амперсанда (&):

example.ru?arg1=value1&arg2=value2

В каждой паре после ключа следует знак равенства (=), а затем значение:

arg1 : value1

arg2 : value2

Такие строки запросов полезны для передачи данных, не требующих взаимодействия со стороны пользователя. Вы можете создавать строки запроса в своем приложении и добавлять их к URL, чтобы данные передавались автоматически при запросе пользователя. 

Этот метод также применим к строкам запросов, сгенерированным формами с использованием метода GET.

  1. Рассмотрим добавление строки запроса в маршрут «query-example». В этом примере мы указываем имя языка программирования, которое будет отображаться на экране. 

Создаем ключ «language» и значение «Python»:

http://127.0.0.1:5000/query-example?language=Python

  1. После запуска приложения и перехода по указанному URL, вы увидите уведомление «Query String Example». Для обработки аргументов запроса вам потребуется написать код, который извлекает значение ключа «language», используя «request.args.get('language')» или «request.args['language']».

При использовании «request.args.get('language')», приложение будет работать, даже если в указанном URL не будет ключа «language». В таком случае метод вернет значение None.

В случае с «request.args['language']» приложение выдаст ошибку 400, если в указанном URL не окажется ключа «language».

Для более надежной работы с запросами, рекомендуется использовать метод «request.args.get()», чтобы избежать возможных сбоев в приложении.

  1. Давайте рассмотрим пример с чтением ключа «language» и выводом его значения. В файле «yourapp.py» измените маршрут «query-example» следующим образом:

  1. После этого запустите приложение и перейдите по следующему URL:

http://127.0.0.1:5000/query-example?language=Python

В браузере вы увидите следующий вывод:

The language value is: Python

Так, значение аргумента из URL привязывается к переменной «language» и возвращается через браузер.

  1. Для добавления дополнительных параметров запроса вы можете прикреплять новые пары ключ-значение в конец URL. 

Например, создадим ключ «framework» со значением «Flask»:

http://127.0.0.1:5000/query-example?language=Python&framework=Flask

  1. Если вам требуется больше параметров, вы можете продолжать добавлять & и пары ключ-значение. 

Создадим ключ «website» со значением «Spaceweb»:

http://127.0.0.1:5000/query-example?language=Python&framework=Flask&website=Spaceweb

  1. Для доступа к этим значениям мы по-прежнему используем методы «request.args.get()» или «request.args[]». Давайте воспользуемся обоими вариантами, чтобы показать, что произойдет при отсутствии ключа. Изменим маршрут «query_example», чтобы присвоить значения переменным и вывести их:

  1. После этого запустите приложение и перейдите по следующему URL:

http://127.0.0.1:5000/query-example?language=Python&framework=Flask&website=Spaceweb

Вывод:

The language value is: Python

The framework value is: Flask

The website value is: Spaceweb

  1. Удалите ключ «language» из URL:

http://127.0.0.1:5000/query-example?framework=Flask&website=Spaceweb

Если значение для «language» отсутствует, в браузере появится значение «None»:

The language value is: None

The framework value is: Flask

The website value is: Spaceweb

  1. Удалите ключ «framework» из URL:

http://127.0.0.1:5000/query-example?language=Python&website=Spaceweb

Браузер выдаст сообщение об ошибке, поскольку он не может получить значение для «framework»:

werkzeug.exceptions.BadRequestKeyError

werkzeug.exceptions.BadRequestKeyError: 400 Bad Request: The browser (or proxy) sent a request that this server could not understand.

KeyError: 'framework'

Теперь перейдем к следующему типу входящих данных.

Использование данных форм

Данные форм поступают из форм, отправленных на маршрут в виде запроса POST. В отличие от передачи данных в URL, данные форм передаются приложению незаметно для пользователя. 

Несмотря на то, что вы не видите передаваемые данные формы, ваше приложение способно считывать их.

  1. Давайте проиллюстрируем это, изменив маршрут «form-example» в «yourapp.py» так, чтобы он принимал запросы как GET, так и POST, и возвращал форму:

# Разрешим как GET-, так и POST-запросы
@app.route('/form-example', methods=['GET', 'POST'])
def form_example():
    return '''
              <form method=«POST»>
                  <div><label>Language: <input type=«text» name=«language»></label></div>
                  <div><label>Framework: <input type=«text» name=«framework»></label></div>
                  <input type=«submit» value=«Submit»>
              </form>'''

  1. Затем запустите приложение и перейдите по URL:

http://127.0.0.1:5000/form-example

Браузер должен отобразить форму с двумя полями ввода: для «language» и «framework», а также кнопку отправки.

  1. Внутри функции обработки запроса необходимо проверить метод запроса: GET или POST. Если это GET-запрос, можно вывести форму. В противном случае (POST-запрос), необходимо обработать входящие данные.

Изменим маршрут «form-example» в «yourapp.py», добавив следующий код программы:


# Разрешим как GET-, так и POST-запросы
@app.route('/form-example', methods=['GET', 'POST'])
def form_example():
    
# Обработка POST-запроса
    if request.method == 'POST':
        language = request.form.get('language')
        framework = request.form.get('framework')
        return '''
                  <h1>The language value is: {}</h1>
                  <h1>The framework value is: {}</h1>'''.format(language, framework)

    # Обработка GET-запроса
    return '''
           <form method=«POST»>
               <div><label>Language: <input type=«text» name=«language»></label></div>
               <div><label>Framework: <input type=«text» name=«framework»></label></div>
               <input type=«submit» value=«Submit»>
           </form>'''

  1. Затем запустите приложение и перейдите по URL:

http://127.0.0.1:5000/form-example

  1. Введите «Python» в поле «language» и «Flask» в поле «framework», затем нажмите кнопку Submit.

Вывод в браузере будет примерно следующим:

The language value is: Python
The framework value is: Flask

Использование данных JSON
 

  1. Приведем пример JSON-объекта:

Такая структура позволяет передавать более сложные данные, чем строки запросов и данные форм. В нашем примере используются вложенные объекты JSON и массив элементов. Flask легко обрабатывает этот формат данных.

  1. Изменим маршрут «json-example» в «yourapp.py», чтобы он принимал только запросы POST и игнорировал другие, в частности, GET:

# Запретим запросы GET
@app.route('/json-example', methods=['POST'])
def json_example():
    return 'JSON Object Example'

Для отправки JSON-объекта мы воспользуемся Postman, который позволяет отправлять настраиваемые запросы через URL.

  1. Добавьте URL в Postman, измените тип запроса на POST. 
  2. Переключитесь на вкладку «body», выберите «raw» и укажите тип данных «JSON» из раскрывающегося списка.

Эти настройки необходимы, чтобы Postman правильно отправлял данные JSON и чтобы ваше Flask-приложение понимало, что оно получает данные JSON:

POST http://127.0.0.1:5000/json-example

Body: raw JSON

  1. Затем вставьте в поле ввода текст предыдущего примера JSON.
  2. Отправьте запрос. В качестве вывода вы получите: «JSON Object Example». Это нормально, так как код для обработки данных JSON в ответе еще не написан.

Для чтения данных мы должны понять, как Flask преобразует данные JSON в структуры данных Python:

  • Все объекты преобразуются в словари Python. {«key» : «value»} в JSON соответствует somedict['key'], что возвращает значение в Python.
  • Массив в JSON преобразуется в список в Python. Синтаксис одинаков, поэтому [1,2,3,4,5] в JSON становится списком в Python.
  • Значения в кавычках объекта JSON становятся строками в Python.
  • Логические операторы true и false становятся True и False в Python.
  • Числа без кавычек становятся числами в Python.
  1. Теперь поработаем с кодом для считывания входящих данных JSON.

Для начала добавим все содержимое JSON-объекта в переменную, используя «request.get_json()». Он преобразует JSON-объект в данные Python. 

Присвоим данные входящего запроса переменным и выведем их, внеся следующие изменения в маршрут «json-example»:

# Запретим запросы GET
@app.route('/json-example', methods=['POST'])
def json_example():
    request_data = request.get_json()

    language = request_data['language']
    framework = request_data['framework']
    python_version = request_data['version_info']['python']
    example = request_data['examples'][0]
    boolean_test = request_data['boolean_test']

    return '''
           The language value is: {}
           The framework value is: {}
           The Python version is: {}
           The item at index 0 in the example list is: {}
           The boolean value is: {}'''.format(language, framework, python_version, example, boolean_test)

  1. Если JSON-объект, отправленный с запросом, не содержит ключ, к которому обращается функция просмотра, запрос не будет выполнен. Если вы не хотите, чтобы запрос завершался ошибкой при отсутствии ключа, вам нужно проверить его наличие:

# Запретим запросы GET
@app.route('/json-example', methods=['POST'])
def json_example():
    request_data = request.get_json()

    language = None
    framework = None
    python_version = None
    example = None
    boolean_test = None

    if request_data:
        if 'language' in request_data:
            language = request_data['language']

        if 'framework' in request_data:
            framework = request_data['framework']

        if 'version_info' in request_data:
            if 'python' in request_data['version_info']:
                python_version = request_data['version_info']['python']

        if 'examples' in request_data:
            if (type(request_data['examples']) == list) and (len(request_data['examples']) > 0):
                example = request_data['examples'][0]

        if 'boolean_test' in request_data:
            boolean_test = request_data['boolean_test']

    return '''
           The language value is: {}
           The framework value is: {}
           The Python version is: {}
           The item at index 0 in the example list is: {}
           The boolean value is: {}'''.format(language, framework, python_version, example, boolean_test
)

  1. Запустите приложение и отправьте запрос JSON с использованием Postman. 

В ответе вы увидите примерно следующее:

The language value is: Python
The framework value is: Flask
The Python version is: 3.9.0
The item at index 0 in the example list is: query
The boolean value is: true

Готово! Теперь вы понимаете, как обрабатывать данные в формате JSON.

Заключение

Эффективная обработка входящих запросов в Flask – это один из ключевых аспектов разработки веб-приложений. В этом руководстве мы рассмотрели различные методы взаимодействия с входящими данными: от использования строк запросов и данных форм до работы с более сложными объектами JSON, 

Гибкость и удобство использования Flask делают его мощным инструментом для обработки данных, открывая разработчикам широкие возможности в создании динамичных и отзывчивых веб-приложений.