WSGI.

Любое web-приложение, написанное с использованием Flask, является так называемым WSGI-приложением. WSGI, Web Server Gateway Interface, о котором я уже писал в курсе по "ключевым аспектам Web-разработки", используется практически всеми web-фреймворками для Python и представляет собой соглашение об описании web-приложения в виде обычной функции request -> response (я немного упростил, но суть примерно такая).

Приложение-функцию может вызывать любой WSGI-сервер, который берёт на себя работу с сетью, запуск нужного количества копий приложения и раздачу им запросов. В боевых условиях у вас будет сервер (устройство) с многоядерным процессором, а одновременных запросов будет приходить по многу каждую секунду. Интерпретатор Python в силу особенностей реализации многопоточности, не слишком эффективно работает с большим количеством одновременных задач. WSGI-сервер "в курсе" этих особенностей и позволяет эффективно использовать ресурсы железа, запуская несколько одновременно работающих интерпретаторов, следя за каждым из них и раздавая им запросы поровну. А WSGI (сам интерфейс) позволяет web-разработчикам использовать все блага WSGI-серверов вне зависимости от выбранного фреймворка!

До этого момента мы запускали наше приложение с помощью команды flask. Эта команда запускает WSGI-приложение на сильно упрощённом сервере разработчика. Этот сервер может обрабатывать только один запрос за раз, не позволяет запускать несколько интерпретаторов. Но зато его не нужно настраивать, а приложение он умеет перезапускать сам, как только код будет изменён. Это очень важные качества на этапе разработки. Поэтому web-разработчик обычно использует и dev-сервер и полноценный WSGI-сервер — один при разработке, а второй в боевых условиях. Запустим же наше приложение на WSGI-сервере и мы!

Gunicorn.

Одним из самых популярных WSGI-серверов является gunicorn. Установим же его в наш проект (в то же виртуальное окружение, в который вы установили flask):

$ pip install gunicorn

Когда gunicorn будет установлен, для запуска приложения вместо команды flask можно будет запустить приложение так (я предполагаю, что виртуальное окружение активировано, ваше приложение описано в файле hello_world.py и Flask-объект присвоен переменной app):

$ gunicorn --workers=4 --bind=127.0.0.1:5000 hello_world:app

Это пример типичной команды для запуска, который показывает две самых важных опции gunicorn: указание количества интерпретаторов, которые будут выполнять код вашего приложения (они называются воркерами, "workers"), а так же адреса, запросы к которому и будет обслуживать сервер. Вот соответствующие опции в приведённой команде:

  • --workers=4 означает "использовать четыре воркера",
  • --bind=127.0.0.1:5000 "слушать порт 5000 на хосте 127.0.0.1".

WSGI-приложение указывается в виде "полное.имя.модуля:переменная". Запомните, вы указываете не имя файла, а именно имя модуля (или пакета), который экспортирует переменную, ссылающуюся на WSGI-приложение (объект Flask).

Доставка приложений до сервера.

При настройке физического сервера вам будет нужно единожды установить Python и gunicorn. Само же приложение можно доставлять и обновлять разными способами.

Можно склонировать git-репозиторий на сервер и периодически подтягивать изменения. Этот способ — не самый хороший. Но иногда удобный для тестовых серверов. Не требует релиза пакетов и вообще хоть какого-то версионирования. Вы даже можете не оформлять код, как пригодный для дистрибуции пакет. А ещё при таком варианте доставки можно прямо на сервере что-то поправить в коде и закоммитить, но не нужно так делать, поверьте!

Более практичный вариант: установка и обновление пакета прямо из Git с помощью pip. Потребует оформления кода в виде пакета, пригодного для дистрибуции (и установки с помощью pip). Но сам дистрибутив можно не собирать и не выкладывать на индексы. Это удобно, если вы не хотите иметь свой индекс, но использовать общий тоже не можете (коммерческая тайна).

И конечно же всегда можно собрать дистрибутив, опубликовать на PyPI или свой индекс и устанавливать на сервер оттуда (с помощью pip). Но не советую публиковать ваши проекты на общий PyPI: всё же PyPI предназначен для хранения библиотек, которые полезны всему сообществу, а не пакетов, интересных только лишь лично вам :)

Когда приложение доставлено на сервер и видно интерпретатору (в случае первого варианта доставки вам потребуется указать питону, где искать исходники), вам останется только настроить автоматический запуск gunicorn с нужными опциями. О том, как это сделать в конкретной ОС, вы всегда сможете найти сами.

Задание.

  1. Установите в окружение проекта пакет gunicorn.
  2. Запустите ваше приложение с помощью gunicorn.
  3. Добавьте соответствующую команду в Makefile.
Мы учим программированию с нуля до стажировки и работы. Попробуйте наш бесплатный курс «Введение в программирование» или полные программы обучения по Node, PHP, Python и Java.

Хекслет

Подробнее о том, почему наше обучение работает →