Spec-Zone.ru › Python 3.14

zipapp — управление исполняемыми ZIP-архивами Python

Добавлено в версии 3.5.

Исходный код: Lib/zipapp.py

Этот модуль предоставляет инструменты для создания ZIP-файлов с кодом Python, которые можно непосредственно выполнить с помощью интерпретатора Python. Модуль предоставляет как интерфейс командной строки, так и API Python.

Простой пример

В следующем примере показано, как с помощью интерфейса командной строки создать исполняемый архив из каталога с кодом Python. При запуске архива будет выполнена функция main из модуля myapp в архиве.

$ python -m zipapp myapp -m "myapp:main"
$ python myapp.pyz
<output from myapp>

Интерфейс командной строки

При вызове в качестве программы из командной строки используется следующая форма:

$ python -m zipapp source [options]

Если source — это каталог, из его содержимого будет создан архив. Если source — это файл, он должен быть архивом; этот файл будет скопирован в целевой архив (или будет отображено содержимое его строки shebang, если указана опция –info).

Доступны следующие опции:

-o <output>, --output=<output>

Записать результат в файл с именем output. Если эта опция не указана, выходной файл будет иметь то же имя, что и входной source, с добавленным расширением .pyz. Если указано явное имя файла, оно используется без изменений (поэтому при необходимости следует включить расширение .pyz).

Если source — архив, имя выходного файла необходимо указать (и в этом случае output не должен совпадать с source).

-p <interpreter>, --python=<interpreter>

Добавить в архив строку #!, указывающую interpreter в качестве команды для запуска. Кроме того, в POSIX сделать архив исполняемым. По умолчанию строка #! не добавляется, а файл не делается исполняемым.

-m <mainfn>, --main=<mainfn>

Записать в архив файл __main__.py, который запускает mainfn. Аргумент mainfn должен иметь форму «pkg.mod:fn», где «pkg.mod» — пакет или модуль в архиве, а «fn» — вызываемый объект в указанном модуле. Файл __main__.py выполнит этот вызываемый объект.

При копировании архива нельзя указывать --main.

-c, --compress

Сжимать файлы методом deflate, уменьшая размер выходного файла. По умолчанию файлы сохраняются в архиве без сжатия.

При копировании архива --compress не действует.

Добавлено в версии 3.7.

--info

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

-h, --help

Вывести краткое сообщение об использовании и завершить работу.

API Python

Модуль определяет две вспомогательные функции:

zipapp.create_archive(source, target=None, interpreter=None, main=None, filter=None, compressed=False)

Создать архив приложения из source. В качестве источника можно указать:

  • Имя каталога или объект, подобный пути, указывающий на каталог. В этом случае из содержимого каталога будет создан новый архив приложения.
  • Имя существующего файла архива приложения или объект, подобный пути, указывающий на такой файл. В этом случае файл копируется в целевое расположение (с изменением в соответствии со значением аргумента interpreter). При необходимости имя файла должно включать расширение .pyz.
  • Файловый объект, открытый для чтения в двоичном режиме. Содержимое файла должно быть архивом приложения; предполагается, что файловый объект находится в начале архива.

Аргумент target определяет, куда будет записан полученный архив:

  • Если это имя файла или объект, подобный пути, архив будет записан в этот файл.
  • Если это открытый файловый объект, архив будет записан в него. Файловый объект должен быть открыт для записи в двоичном режиме.
  • Если аргумент target не указан (или равен None), источником должен быть каталог, а целевым файлом станет файл с тем же именем, что и у источника, с добавленным расширением .pyz.

Аргумент interpreter задаёт имя интерпретатора Python, с помощью которого будет запущен архив. В начале архива записывается строка «shebang». В POSIX она обрабатывается ОС, а в Windows — программой запуска Python. Если аргумент interpreter не указан, строка shebang не записывается. Если интерпретатор указан, а целевой объект — имя файла, для целевого файла устанавливается бит исполняемого файла.

Аргумент main задаёт имя вызываемого объекта, который будет использоваться в качестве главной программы архива. Его можно указать только в том случае, если источником является каталог, в котором ещё нет файла __main__.py. Аргумент main должен иметь форму «pkg.module:callable»; запуск архива выполняется путём импорта «pkg.module» и вызова указанного объекта без аргументов. Если источником является каталог без файла __main__.py, аргумент main необходимо указать, иначе полученный архив нельзя будет выполнить.

Необязательный аргумент filter задаёт функцию обратного вызова, которой передаётся объект Path, представляющий путь к добавляемому файлу (относительно исходного каталога). Если файл нужно добавить, функция должна вернуть True.

Необязательный аргумент compressed определяет, будут ли файлы сжаты. Если он установлен в True, файлы в архиве сжимаются методом deflate; в противном случае они сохраняются без сжатия. Этот аргумент не действует при копировании существующего архива.

Если для source или target указан файловый объект, вызывающий код отвечает за его закрытие после вызова create_archive.

При копировании существующего архива переданные файловые объекты должны поддерживать только методы read и readline либо write. При создании архива из каталога, если целевой объект является файловым объектом, он будет передан классу zipfile.ZipFile и должен предоставлять методы, необходимые этому классу.

Изменено в версии 3.7: Добавлены параметры filter и compressed.

zipapp.get_interpreter(archive)

Возвращает интерпретатор, указанный в строке #! в начале архива. Если строка #! отсутствует, возвращает None. Аргумент archive может быть именем файла или файловым объектом, открытым для чтения в двоичном режиме. Предполагается, что он находится в начале архива.

Примеры

Упакуйте каталог в архив и запустите его.

$ python -m zipapp myapp
$ python myapp.pyz
<output from myapp>

То же самое можно сделать с помощью функции create_archive():

>>> import zipapp
>>> zipapp.create_archive('myapp', 'myapp.pyz')

Чтобы приложение можно было непосредственно выполнить в POSIX, укажите используемый интерпретатор.

$ python -m zipapp myapp -p "/usr/bin/env python"
$ ./myapp.pyz
<output from myapp>

Чтобы заменить строку shebang в существующем архиве, создайте изменённый архив с помощью функции create_archive():

>>> import zipapp
>>> zipapp.create_archive('old_archive.pyz', 'new_archive.pyz', '/usr/bin/python3')

Чтобы обновить файл на месте, выполните замену в памяти с помощью объекта BytesIO, а затем перезапишите исходный файл. Обратите внимание: при перезаписи файла на месте ошибка может привести к потере исходного файла. Этот код не защищает от таких ошибок, но в рабочем коде такая защита необходима. Кроме того, этот способ работает только в том случае, если архив помещается в памяти:

>>> import zipapp
>>> import io
>>> temp = io.BytesIO()
>>> zipapp.create_archive('myapp.pyz', temp, '/usr/bin/python2')
>>> with open('myapp.pyz', 'wb') as f:
>>>     f.write(temp.getvalue())

Указание интерпретатора

Обратите внимание: если вы укажете интерпретатор, а затем будете распространять архив приложения, необходимо убедиться, что используемый интерпретатор переносим. Программа запуска Python для Windows поддерживает большинство распространённых форм строк #! в POSIX, однако следует учитывать и другие моменты:

  • Если используется «/usr/bin/env python» (или другие формы команды «python», например «/usr/bin/python»), следует учитывать, что у пользователей по умолчанию может быть установлен Python 2 или Python 3, и писать код, совместимый с обеими версиями.
  • Если используется явная версия, например «/usr/bin/env python3», приложение не будет работать у пользователей, у которых эта версия не установлена. (Это может быть желаемым поведением, если ваш код несовместим с Python 2.)
  • Нельзя указать «python версии X.Y или новее», поэтому будьте осторожны с точным указанием версии, например «/usr/bin/env python3.4»: для пользователей Python 3.5, например, строку shebang придётся изменить.

Как правило, следует использовать «/usr/bin/env python2» или «/usr/bin/env python3» в зависимости от того, для Python 2 или Python 3 написан ваш код.

Создание автономных приложений с помощью zipapp

С помощью модуля zipapp можно создавать автономные программы Python, распространяемые среди конечных пользователей, которым достаточно установить подходящую версию Python в своей системе. Для этого нужно поместить в архив все зависимости приложения вместе с его кодом.

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

  1. Создайте приложение в каталоге обычным способом: в нём должны находиться каталог myapp с файлом __main__.py и весь необходимый вспомогательный код приложения.
  2. Установите все зависимости приложения в каталог myapp с помощью pip:

    $ python -m pip install -r requirements.txt --target myapp
    

    (предполагается, что зависимости проекта перечислены в файле requirements.txt; если это не так, их можно просто указать вручную в командной строке pip).

  3. Упакуйте приложение с помощью команды:

    $ python -m zipapp -p "interpreter" myapp
    

В результате будет создан самостоятельный исполняемый файл, который можно запускать на любом компьютере с подходящим интерпретатором. Подробности см. в разделе Указание интерпретатора. Файл можно распространять среди пользователей отдельно.

В Unix файл myapp.pyz уже является исполняемым. При желании можно переименовать файл, удалив расширение .pyz, чтобы получить «обычное» имя команды. В Windows файл myapp.pyz[w] является исполняемым, поскольку при установке интерпретатор Python регистрирует расширения файлов .pyz и .pyzw.

Ограничения

Если приложение зависит от пакета, содержащего расширение C, этот пакет нельзя запускать из ZIP-файла (это ограничение ОС: для загрузки исполняемого кода загрузчику ОС он должен присутствовать в файловой системе). В этом случае можно исключить зависимость из ZIP-файла и либо потребовать, чтобы пользователи установили её самостоятельно, либо распространять её вместе с ZIP-файлом и добавить в __main__.py код, включающий каталог с распакованным модулем в sys.path. В таком случае необходимо распространять подходящие двоичные файлы для целевых архитектур (и, возможно, выбирать правильную версию для добавления в sys.path во время выполнения в зависимости от компьютера пользователя).

Формат архива ZIP-приложения Python

Начиная с версии 2.6 Python может выполнять ZIP-файлы, содержащие файл __main__.py. Чтобы Python мог выполнить архив приложения, достаточно, чтобы это был стандартный ZIP-файл, содержащий файл __main__.py, который будет запущен в качестве точки входа приложения. Как и в случае с любым скриптом Python, родительский каталог скрипта (в данном случае ZIP-файл) будет помещён в sys.path, поэтому из ZIP-файла можно импортировать и другие модули.

Формат ZIP-файла допускает добавление произвольных данных перед ZIP-файлом. Формат ZIP-приложения использует эту возможность, чтобы добавить в начало файла стандартную строку «shebang» POSIX (#!/path/to/interpreter).

Таким образом, формат ZIP-приложения Python формально определяется следующим образом:

  1. Необязательная строка shebang, содержащая символы b'#!', за которыми следует имя интерпретатора, а затем символ новой строки (b'\n'). Имя интерпретатора может быть любым, допустимым для обработки строк «shebang» в ОС или программой запуска Python в Windows. В Windows имя интерпретатора должно быть закодировано в UTF-8, а в POSIX — в кодировке sys.getfilesystemencoding().
  2. Стандартные данные ZIP-файла, сформированные модулем zipfile. ZIP-файл должен содержать файл с именем __main__.py (он должен находиться в «корне» ZIP-файла, то есть не может располагаться во вложенном каталоге). Данные ZIP-файла могут быть сжаты или не сжаты.

Если в архиве приложения есть строка shebang, в системах POSIX для него можно установить бит исполняемого файла, чтобы запускать его напрямую.

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

© 2001 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.14/library/zipapp.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API