Упаковка приложений Python в форму самораспаковывающихся исполняемых файлов с помощью Pyinstaller

В этой короткой статье мы рассмотрим простой способ, который позволяет распространять приложения, созданные с помощью языка Python в виде “толстых” самораспаковывающихся архивов, которые внешне выглядят как простые исполняемые файлы и содержат в своем составе все окружение и зависимости, необходимые для выполнения приложения.

Впервые такая задача возникла у нас при распространении агентов для системы, в которой на узлах были ограничения на установку стороннего ПО. Обычный подход с установкой зависимостей и дополнительных библиотек через систему управления пакетами, PIP или в форме контейнеров Docker не был возможен, поэтому мы начали искать средство, которое бы позволило нам упаковать все необходимое в единый исполняемый файл.

Поклонники языка Go часто приводят способ распространения в виде единого файла как одно из ключевых преимуществ экосистемы Go. Метод данной статьи позволяет осуществить похожую, хоть и не равнозначную поставку ПО с помощью Python.

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

Pyinstaller разработан так, чтобы поддерживать библиотеки Python по-умолчанию, однако, разработчики ведут список протестированных компонентов, среди которых можно найти парочку, которые не поддерживаются. Фактически, это означает, что вам придется самостоятельно убедиться в том, что ваше ПО может успешно распространяться с помощью Pyinstaller. К примеру, мы успешно использовали следующие библиотеки в составе нашего ПО:

mysql-connector
tornado
pyhocon

При этом ни одна из них на момент публикации не заявлена как проверенная, однако, мы не встретили ни одной проблемы. Впрочем, авторы поддерживают специальную страницу When Things Go Wrong , на которой вы можете узнать что делать в случае проблем.

Поддерживаемые версии Python

На момент публикации статьи Pyinstaller поддерживает Python версий 2.7, 3.4-3.7.

Простая сборка приложения с помощью Pyinstaller

Сформируем requirements.txt, все библиотеки, кроме pyinstaller приведены для примера и не требуются для работы pyinstaller:

pyinstaller
mysql-connector
tornado
pyhocon

Установим зависимости с помощью PIP:

pip install --user -r requirements.txt

Соберем наше приложение:

pyinstaller --workpath /tmp/build --specpath /tmp -F application.py

Флаг -F определяет, что все будет упаковано в единый исполняемый файл. Пути --workpath и --specpath определяют где будет размещаться сборочная информация, которая будет использоваться для текущей и для последующих сборок.

Кросскомпиляция

Pyinstaller не поддерживает кросскомпиляцию из одной платформы для всех возможных. Авторы советуют развертывать для каждой сборочной среды свою платформу. В некоторых случаях это может быть недостатком, поскольку требует поддержки нескольких сборочных сред и может создать проблемы для простой сборки с использованием стандартных средств CI/CD, которые ориентируются на вызов единого обработчика.

Если вам понравилась статья, поделитесь ей с друзьями.