Python PEX: Создание Исполняемых Python-Приложений с Зависимостями
Python PEX: Создание Исполняемых Python-Приложений с Зависимостями
Полное руководство с примерами и лучшими практиками
Что такое PEX?
PEX (Python Executable) — технология упаковки Python-проектов в единый исполняемый файл (с расширением .pex), содержащий код, зависимости и метаданные. Разработанный Twitter (ныне X) и поддерживаемый сообществом, PEX решает ключевые проблемы:
- Упрощение деплоя (без
pip install). - Изоляция зависимостей.
- Кроссплатформенность (при наличии совместимого Python).
Как это работает?
PEX-файл — это ZIP-архив со структурой:
├── PEX-INFO # Метаданные (зависимости, точка входа)
├── .bootstrap/ # Скрипты инициализации
├── .deps/ # Установленные пакеты (wheels)
└── your_code.py # Ваш код
При запуске PEX распаковывает зависимости в изолированное окружение и выполняет код.
Установка PEX
pip install pex
Проверка: pex --version → pex 2.1.143
Создание PEX: Пошаговые Примеры
Пример 1: Простой скрипт с внешней зависимостью
- Исходный код (
main.py):
import requests
from colorama import Fore, init
init(autoreset=True)
def get_ip():
response = requests.get("https://httpbin.org/ip")
return response.json()["origin"]
if __name__ == "__main__":
ip = get_ip()
print(Fore.GREEN + f"Ваш IP: {ip}")
- Зависимости (
requirements.txt):
requests
colorama
- Сборка PEX:
pex -r requirements.txt -e main:get_ip -o ip_tool.pex
-r requirements.txt: установка зависимостей.-e main:get_ip: точка входа (файл:функция).-o ip_tool.pex: имя выходного файла.
Запуск:
./ip_tool.pex
# Результат: Ваш IP: 192.168.1.1 (в цвете)
Пример 2: Пакет с setup.py
Структура проекта:
myapp/
├── setup.py
└── myapp/
├── __init__.py
└── cli.py
setup.py:
from setuptools import setup, find_packages
setup(
name="myapp",
version="0.1",
packages=find_packages(),
entry_points={"console_scripts": ["myapp = myapp.cli:main"]},
install_requires=["click>=8.0", "tabulate"],
)
cli.py:
import click
from tabulate import tabulate
@click.command()
@click.option("--name", prompt="Ваше имя", help="Имя пользователя")
def main(name):
table = [["Привет,", name], ["PEX", "работает!"]]
print(tabulate(table, tablefmt="fancy_grid"))
- Сборка PEX:
pex . -c myapp -o app.pex # '.' указывает на текущий каталог с setup.py
-c myapp: имя консольного скрипта изentry_points.
Запуск:
./app.pex --name=Анна
# Вывод таблицы с приветствием.
Продвинутые Сценарии
1. Зависимости из разных источников
pex requests "flask>=2.0" git+https://github.com/user/repo.git -o app.pex
2. Multi-платформенная сборка
Укажите платформы явно (требует предварительной компиляции wheels):
pex -r requirements.txt \
--platform=manylinux2014_x86_64 \
--platform=macosx_12_0_arm64 \
-o app.pex
3. Включение ресурсов
Добавьте файлы через --resources:
pex -r requirements.txt -e main:main \
--resources-dir templates/="templates/*" \
-o app.pex
4. Переменные окружения
pex --python=python3.11 -o app.pex # Фиксация версии Python
Лучшие Практики
-
Минимизация размера:
Используйте--no-indexс локальным кэшем wheels:pex -r requirements.txt --no-index --find-links=./wheels_dir -o app.pex -
Тестирование PEX:
Запуск тестов внутри PEX:pex -r requirements.txt -p pytest -o test.pex ./test.pex tests/ -
Интерактивный режим:
./app.pex -m IPython # Запуск IPython с зависимостями -
Интеграция с Docker:
FROM python:3.11-slim COPY app.pex /app.pex ENTRYPOINT ["/app.pex"]
Ограничения PEX
- Нет статической линковки: Требует установленного Python.
- Размер файла: Может быть крупным (все зависимости внутри).
- Системные библиотеки: Не включает низкоуровневые зависимости (например,
libssl).
PEX vs. Другие Инструменты
| Инструмент | Преимущества | Недостатки |
|---|---|---|
| PEX | Запуск без установки, изоляция, кроссплатформенность | Требует Python, размер файла |
| PyInstaller | Полностью автономный бинарник | Сложность сборки под несколько ОС |
| Docker | Полная изоляция, любые зависимости | Требует Docker, тяжёлые образы |
| zipapp | Встроен в Python, простой | Нет управления зависимостями |
Отладка PEX
- Просмотр содержимого:
unzip -l app.pex - Verbose-режим:
PEX_VERBOSE=5 ./app.pex - Путь к кэшу зависимостей:
export PEX_ROOT=/custom/cache/path
Заключение
PEX — мощный инструмент для:
✅ Быстрого деплоя скриптов и приложений.
✅ Создания переносимых CLI-утилит.
✅ Упрощения CI/CD-пайплайнов.
Пример итогового workflow:
# Сборка
pex -r requirements.txt -e app:main --platform=manylinux2014_x86_64 -o release.pex
# Деплой на сервер
scp release.pex user@server:/app/
# Запуск
ssh user@server "/app/release.pex"
Используйте PEX для проектов, где важна скорость развёртывания и переносимость!
Дополнительные ресурсы:
Статья охватывает ключевые аспекты PEX: от базовых примеров до продвинутых сценариев. Для глубокого изучения рекомендуется экспериментировать с реальными проектами и изучать исходный код PEX на GitHub.