Найти в Дзене

Python PEX: создание исполняемых Python-приложений с зависимостями

PEX (Python Executable) — технология упаковки Python-проектов в единый исполняемый файл (с расширением .pex), содержащий код, зависимости и метаданные. Разработанный Twitter (ныне X) и поддерживаемый сообществом, PEX решает ключевые проблемы: - Упрощение деплоя (без pip install). - Изоляция зависимостей. - Кроссплатформенность (при наличии совместимого Python). Как это работает? PEX-файл — это ZIP-архив со структурой: ├── PEX-INFO # Метаданные (зависимости, точка входа) ├── .bootstrap/ # Скрипты инициализации ├── .deps/ # Установленные пакеты (wheels) └── your_code.py # Ваш код При запуске PEX распаковывает зависимости в изолированное окружение и выполняет код. pip install pex Проверка: pex --version → pex 2.1.143 Пример 1: Простой скрипт с внешней зависимостью 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()[
Оглавление

Что такое 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: Простой скрипт с внешней зависимостью

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}")

2. Зависимости (`requirements.txt`):

requests
colorama

3. Сборка 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

1. `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"],
)

2. `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"))

3. Сборка 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

Лучшие Практики

1. Минимизация размера:

Используйте `--no-index` с локальным кэшем wheels:

pex -r requirements.txt --no-index --find-links=./wheels_dir -o app.pex

2. Тестирование PEX:

Запуск тестов внутри PEX:

pex -r requirements.txt -p pytest -o test.pex
./test.pex tests/

3. Интерактивный режим:

./app.pex -m IPython # Запуск IPython с зависимостями

4. Интеграция с 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 для проектов, где важна скорость развёртывания и переносимость!

Подписывайтесь:

Телеграм https://t.me/lets_go_code
Канал "Просто о программировании"
https://dzen.ru/lets_go_code