Начало работы с Flask 3.0

автор vadim


Одной из причин, по которой Python является лучшим выбором для веб-разработки, является широта веб-фреймворков, доступных на этом языке. Среди наиболее популярных и полезных — Flask, который позволяет начать с простого («по одной капле за раз»), но расширяется вместе с вашим приложением, добавляя практически все необходимые вам функции.

В этой статье мы рассмотрим настройку и использование Flask 3.0 для базовых веб-приложений. Мы также коснемся использования Jinja2 для создания шаблонов и решения распространенных проблем, таких как изменение типов ответов и обработка перенаправлений.

Настройка Флакса

Flask 3.0 прост в настройке. Использовать pip install flask для установки Flask и всех его зависимостей, включая систему шаблонов Jinja2.

Как и в случае с любой другой средой Python, лучше всего создавать проект с использованием Flask внутри виртуальной среды Python. Это изолирует ваш проект от основной установки Python и от других проектов, которые могут использовать Flask и его зависимости (поскольку вы можете поддерживать разные версии для разных проектов).

Обратите внимание: если вы хотите установить Flask с поддержкой асинхронных функций или сопрограмм, используйте pip install flask[async]. Вскоре я расскажу подробнее об использовании Flask с async.

Базовое приложение Flask

Простое приложение Flask с одним маршрутом можно написать всего в несколько строк кода. Сохраните следующий простой пример приложения в файле с именем app.py:


from flask import Flask

app = Flask(__name__)

@app.route("https://www.infoworld.com/")
def home():
    return "Hello, world"

Это приложение мало что делает — оно просто создает веб-сайт с одним маршрутом, который отображает в браузере «Привет, мир».

Вот что делает каждый элемент:

  • Линия app = Flask(__name__) создает новый экземпляр приложения Flask с именем app. Класс Flask принимает аргумент, который является именем модуля или пакета приложения. Проходя это __name__ (имя текущего модуля) — это быстрый способ использовать текущий модуль в качестве отправной точки приложения. Теоретически вы можете использовать любое имя, но по умолчанию принято использовать имя модуля.
  • app.route Декоратор используется для обертывания функции и указания функции, которую следует использовать для доставки ответа по заданному маршруту. В данном случае маршрутом является корень сайта ("https://www.infoworld.com/"), а ответом является строка "Hello, world".

Чтобы запустить приложение, используйте python -m flask run в том же каталоге, что и app.py. В консоли вы должны увидеть что-то вроде следующего:


 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

Если вы откроете веб-браузер для http://127.0.0.1:5000/вы должны увидеть слова «Привет, мир».

Обратите внимание, что вы можете назвать основной файл вашего приложения Flask как угодно, но называя его app.py позволяет Flask распознавать его автоматически. Чтобы использовать другое имя, вам необходимо сначала установить FLASK_APP переменной среды к имени нового файла минус его расширение (например, hello для hello.py).

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

Маршруты и переменные маршрута в Flask

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

В этом примере, где у нас есть маршрут в формате /hi/ за которым следует имя пользователя, имя извлекается и передается функции как переменная имя пользователя.


@app.route("/hi/<username>")
def greet(username):
    return f"Hello, {username}"

Посетите этот маршрут с /hi/Serdarи ты увидишь “Hello, Serdar” в браузере.

Типы переменных маршрута Flask

Переменные маршрута также могут быть ограниченный по типудобавив к ним информацию о типе.

Например, если вы используете <int:userid>что обеспечивает userid будет только целым числом. Если вы используете <path:datapath>часть URL-адреса, начиная с этой позиции, будет извлечена в переменную datapath. С этой целью, если бы у нас был маршрут типа /show/<path:datapath>и использовал URL-адрес /show/main/infoзатем main/info будет передано в переменной datapath. (Подробнее о переменных маршрута, ограничивающих тип, см. в документации Flask.)

Обратите внимание, что вам нужно быть осторожным при использовании нескольких одинаковых путей с разными типами данных. Если у вас есть маршрут /data/<int:userid> и маршрут /data/<string:username>, любой элемент во второй позиции, который не может быть сопоставлен как целое число, будет сопоставлен как строка. По возможности избегайте подобных структур маршрутов, поскольку они могут стать запутанными и трудными для отладки. Будьте максимально однозначны в своих маршрутах.

Методы маршрутизации в Flask

Декораторы маршрутов также могут указать методы используется для доступа к маршруту. Вы можете создать несколько функций для обработки одного маршрута разными методами, например:


@app.route('/post', methods=['GET'])
def post_message_route_get():
    return show_post_message_form()

@app.route('/post', methods=['POST'])
def post_message_route_post():
    return post_message_to_site()

Или вы можете объединить маршруты в одну функцию и принимать решения внутри компании на основе этого метода:


from flask import request

@app.route('/post', methods=['GET', 'POST'])
def post_message_route():
    if request.method == 'POST':
        return post_message_to_site()
    # defaults to GET if not POST
    return show_post_message_form()

Обратите внимание, что нам нужно импортировать глобальный request объект для доступа к свойству метода. Мы рассмотрим это подробно позже.

Flask 2.0 и выше также позволяют использовать app.get и app.post в качестве ярлыков. Вышеупомянутые маршруты также могут быть выражены как:


@app.get('/post')
def post_message_route_get():
    return show_post_message_form()

@app.post('/post')
def post_message_route_post():
    return post_message_to_site()

Запрос данных в Flask

В последнем разделе мы получили метод, используемый для вызова маршрута из глобального request объект. request — это экземпляр объекта Request, из которого мы можем получить множество других сведений о запросе — его заголовки, файлы cookie, данные формы, загрузки файлов и т. д.

Некоторые общие свойства Request объект включает в себя:

  • .args: словарь, содержащий параметры URL. Например, URL-адрес с такими аргументами, как ?id=1 будет выражен как словарь {"id": 1}.
  • .cookies: словарь, в котором хранятся все файлы cookie, отправленные в запросе.
  • .files: словарь, содержащий любые файлы, загруженные по запросу, где ключом для каждого элемента является имя файла.
  • .form: словарь, содержащий данные формы запроса, если таковые имеются.
  • .headers: необработанные заголовки запроса.
  • .method: метод, используемый запросом (например, GET, POST).

Возврат ответов в Flask

Когда функция маршрута возвращает данные, Flask делает предположение, чтобы интерпретировать то, что было возвращено:

  • Объекты ответа возвращаются как есть. Создание объекта ответа дает вам детальный контроль над тем, что вы возвращаете клиенту, но в большинстве случаев вы можете использовать один из элементов ниже.
  • Строки, включая выходные данные шаблонов Jinja2 (подробнее об этом далее), преобразуются в Response объекты, с 200 OK код состояния и тип MIME text/html.
  • Словари конвертируются в JSON.
  • Кортежи могут быть любыми из следующих:
    • (ответ, код состояния [int])
    • (ответ, заголовки [list/dict])
    • (ответ, код состояния [int]заголовки [list/dict])

Как правило, лучше всего возвращать то, что лучше всего проясняет работу функции маршрута. Например, обработчик ошибки 404 может возвращать кортеж из двух элементов — код ошибки 404 и сведения о сообщении об ошибке. Это сохраняет функцию маршрутизации незагроможденной.

Шаблоны во Flask

Flask включает в себя механизм шаблонов Jinja2 для программного создания HTML-вывода из данных. Вы используете render_template для генерации HTML, затем передайте переменные, которые будут использоваться в шаблоне.

Вот пример того, как это выглядит в маршруте:


from flask import render_template

@app.route('/hi/<username>')
def greet(username=None):
    return render_template('hello.html', username=username)

Шаблоны, на которые ссылается render_template по умолчанию находятся в подкаталоге каталога проекта Flask с именем templates. С этой целью следующий файл будет находиться в templates/hello.html:


<!doctype html>
<title>Hi there</title>
{% if username %}
  <h1>Hello {{ username }}!</h1>
{% else %}
  <h1>Hello, whoever you are!</h1>
{% endif %}

Шаблоны Jinja2 сами по себе являются чем-то вроде языка, но этот фрагмент должен дать вам представление о том, как они работают. Блоки, обозначенные {% %} содержат логику шаблона и блоки с {{ }} содержат выражения, которые нужно вставить в этот момент. Когда мы вызвали этот шаблон с помощью render_template выше мы прошли username в качестве аргумента ключевого слова; то же самое будет сделано для любых других переменных, которые мы будем использовать.

Обратите внимание, что в целях безопасности шаблоны Jinja2 имеют ограничения на код, который можно запускать внутри них. Следовательно, вам нужно будет выполнить как можно большую часть обработки для данной страницы. до передавая его в шаблон.

Обработчики ошибок в Flask

Чтобы создать маршрут, обрабатывающий определенный класс ошибок сервера, используйте команду errorhandler декоратор:


@app.errorhandler(404)
def page_not_found(error):
    return f"error: {error}"

В этом приложении при возникновении ошибки 404 результат, возвращаемый клиенту, будет сгенерирован page_not_found функция. error — это исключение, генерируемое приложением, поэтому при необходимости вы можете извлечь из него дополнительную информацию и передать ее обратно клиенту.

Запуск и отладка Flask в производстве

Тестовый сервер Flask, упомянутый ранее в этой статье, не подходит для развертывания Flask в рабочей среде. Для производственных развертываний используйте полностью WSGI-совместимый сервер с app объект, созданный Flask() как приложение WSGI.

В документации Flask содержится подробная информация о развертывании на наиболее распространенных вариантах хостинга, а также сведения о том, как самостоятельно размещать приложения Flask — например, с помощью Apache. mod_wsgi или через uWSGI на Nginx.

Использование асинхронности во Flask

Первоначально Flask не имел явной поддержки асинхронных функций или сопрограмм. Сопрограммы теперь являются стандартной функцией Python, а начиная с версии 2.0 Flask поддерживает асинхронные методы для обработчиков маршрутов. Однако поддержка асинхронности во Flask предоставляется как надстройка, поэтому вам необходимо использовать pip install flask[async] чтобы установить эту функцию.

Вот пример Flask async маршрут:


@app.route("/embed/<embed_id>")
async def get_embed(embed_id):
    data = await async_render_embed(embed_id)
    return data

Поддержка асинхронности Flask не меняет того факта, что он работает как приложение WSGI с одним работником для обработки входящих запросов. Если вы хотите поддерживать длительные запросы, такие как соединения API WebSocket, использования async только в функциях маршрутизации будет недостаточно. Возможно, вы захотите рассмотреть возможность использования платформы Quart, которая API-совместима с Flask, но использует интерфейс ASGI для лучшей обработки длительных запросов и нескольких одновременных запросов.

Дальше читайте это:

  • Лучшее программное обеспечение с открытым исходным кодом 2023 года
  • Сертификаты программирования все еще имеют значение?
  • Облачные вычисления больше не являются пустяком
  • Что такое генеративный ИИ? Искусственный интеллект, который создает
  • Программирование с помощью ИИ: советы и лучшие практики от разработчиков
  • Почему Wasm — это будущее облачных вычислений

Related Posts

Оставить комментарий