Зарегистрируйтесь, чтобы продолжить обучение

HTTP Сессия (запрос и ответ) Python: Веб-разработка (Flask)

Каждая HTTP-сессия определяется двумя вещами — запросом и ответом. Запрос формируется клиентом, например браузером, а ответ — сервером. В этом уроке разберем объекты request и response, которые извлекают данные запроса и формируют ответ. Также покажем способы, с помощью которых из объекта request извлекаются параметры.

Request и response

И запрос и ответ во Flask представлены двумя объектами - request и response, обратиться к которым можно внутри каждого обработчика маршрута:

from flask import request


@app.route("/")
def hello_world():
    return "Hello, World!"

Глобальный объект request используется, чтобы извлекать данные запроса, например, заголовков или содержимого отправленной формы. request - неизменяемый объект. Запрос уже выполнили со стороны клиента, и он не может поменяться:

from flask import request


@app.route("/")
def hello_world():
    print(request.headers)  # Выводит все заголовки
    return "Hello, World!"
curl locahost:5000/
Hello, World!

# в терминале запущенного приложения
Host: localhost:5000
User-Agent: curl/7.81.0
Accept: */*

127.0.0.1 - - "GET / HTTP/1.1" 200 -

Для ответа же используется объект response. По умолчанию Flask самостоятельно формирует объект response и его не нужно передавать явно. Flask сам определяет формат возвращаемого контента из обработчика и подставляет нужный формат данных в заголовке:

from flask import render_template


@app.route("/json/")
def json():
    return {"json": 42}  # Возвращает тип application/json


@app.route("/html/")
def html():
    return "<h1>Hello, world!</h1>"  # Возвращает тип text/html

Если вернуть вместе с телом в виде кортежа-пары еще и число, то клиент получит соответствующий код ответа:

@app.route("/not_found")
def not_found():
    return "Oops!", 404
curl -IS localhost:5000/not_found

HTTP/1.1 404 NOT FOUND
Server: Werkzeug/3.0.6 Python/3.13.0rc2
Content-Type: text/html; charset=utf-8
Content-Length: 5
Connection: close

Разумеется мы не можем перечислить все несуществующие пути, чтобы отдавать по ним коды ошибок. Потому для обработки типичных ошибок вроде «Страница не найдена» во Flask есть особый синтаксис обработчика ошибок. На первый взгляд, обработчик ошибок выглядит как обработчик запросов. Только разница в том, что обработчики ошибок получают в качестве аргумента объект ошибки error. Вот так можно было бы оформить «Страницу 404»:

# вместо пути указываем код ошибки
@app.errorhandler(404)
def not_found(error):
    return "Oops!", 404

В большинстве случаев нам достаточно тела ответа и статуса и не нужно явно использовать объект response - Flask самостоятельно оборачивает в него возвращаемые данные. Но если нам надо большее, то нужно использовать функцию make_response(). Она принимает тело ответа и возвращает объект ответа - flask.Response. Объект ответа можно модифицировать разными способами и затем вернуть из обработчика:

from flask import make_response


@app.route("/hello")
def hello():
    # создаем объект response
    response = make_response("Hello, World!")
    # Устанавливаем заголовок
    response.headers["X-MyHeader"] = "Thats my header!"
    # Меняем тип ответа
    response.mimetype = "text/plain"
    # Задаем статус
    response.status_code = 201
    # Устанавливаем cookie
    response.set_cookie("super-cookie", "42")
    return response

В примере выше мы создали объект ответа с телом 'Hello, World!', затем установили в нем наш заголовок, изменили тип ответа, задали куку и статус ответа. Наконец, собранный ответ вернули из обработчика.

curl -i localhost:5000/hello

HTTP/1.1 201 CREATED
Server: Werkzeug/3.0.6 Python/3.13.0rc2
Content-Type: text/plain; charset=utf-8
Content-Length: 13
X-MyHeader: Thats my header!
Set-Cookie: super-cookie=42; Path=/
Connection: close

Hello, World!%

Параметры запроса

Параметры запроса, или еще их называют query string — это не часть маршрута и они не влияют на выбор обработчика. Связано это с тем, что такие параметры используются для различных вспомогательных целей. Например, параметр page, обозначает страницу просматриваемого списка. Обработчик в такой ситуации всегда один и тот же, а данные показываются разные:

curl 'localhost:8000/users?page=4&per=3'

GET /users

Параметры извлекаются из объекта запроса. По атрибуту request.args возвращается объект, который похож на словарь, несколькими способами:

  • request.args – извлекает все параметры
  • request.args.get(name, default=None, type=None) – извлекает значение конкретного параметра в формате строки. Если параметр не найден, приложение продолжает работу, а метод вернет default. С помощью type можно привести параметр к определенному типу. Если привести к указанному типу невозможно, возникнет исключение ValueError
# равноценно запросу GET localhost/users?page=12&per=5 в браузере
curl -G -d page=12 -d per=5 localhost/users
@app.route("/users/")
def get_users():
    print(request.args)  # => {'page': 12, 'per': 5}
    page = request.args.get("page", 1)
    per = request.args.get("per", 10, type=int)
    # Обработка
    prev_page = (page - 1) * per
    current_page = page * per
    users_at_page = users[prev_page:current_page]
    return users_at_page

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


Самостоятельная работа

  1. Измените в example.py следующий обработчик:
 @app.post('/users')
 def users():
     return 'Users', 302
  1. Выполните POST-запрос на него с помощью curl. Убедитесь, что произошел редирект:
# Подставьте ваши параметры
# --head – покажет заголовки
# -X POST – отправит POST запрос
curl --head -X POST localhost:8000/users

Эталонное приложение


Дополнительные материалы

  1. Request
  2. Response

Для полного доступа к курсу нужен базовый план

Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.

Получить доступ
1000
упражнений
2000+
часов теории
3200
тестов

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно

  • 130 курсов, 2000+ часов теории
  • 1000 практических заданий в браузере
  • 360 000 студентов
Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff