跳转到主要内容

一个在任何地方运行任何项目(具有任何虚拟环境依赖项)的Python打包工具。

项目描述

PyEmpaq

一个简单但强大的Python打包工具,可以将任何项目(见下文限制)转换为单个.pyz文件,并将项目的内容打包在其中。

使用PyEmpaq,您可以将任何Python项目(见下文限制)转换为单个.pyz文件,并将所有项目内容打包在其中。

打包非常简单,请参见此演示

pack-demo

该单个文件就是需要分发的全部内容。当最终用户执行它时,原始项目将被展开,其依赖项将在虚拟环境中安装,然后执行。请注意,不需要特殊权限或特权,因为所有操作都在用户环境中进行。

看看它是如何工作的

run-demo

打包和执行都是完全多平台的。这意味着您可以在Linux、Windows、Mac或任何地方打包项目,并且它将在Linux、Windows、Mac或任何地方正常运行。唯一的要求是Python已经安装。

您可以使用PyEmpaq尝试一些打包示例,非常简单,只需下载这些文件之一并用Python运行它

logo

您可以直接从 PyPI 安装 pyempaq;请参阅以下说明

PyEmpaq 安全友好,当您使用它分发项目时,没有任何晦涩或秘密的内容:任何人都可以打开 pyz 文件(它只是一个 ZIP 文件)并检查它。

在分发打包的软件时,它在许可证方面也是安全的。与依赖内部大型数据块打包的机制不同,使用 PyEmpaq,您无需担心软件依赖项(及其依赖项)的许可证问题,在分发它们时。

限制

有一些限制

  • 仅支持 Python >= 3.7

  • 仅支持 Linux、Windows 和 Mac

  • 仅支持 pip 可安装的依赖项(来自 PyPI 或其他来源)。

  • 仅支持纯 Python 或提供 wheels 的依赖项。

这意味着大多数项目都可以使用 PyEmpaq 打包和运行。如果您有任何关于如何克服这些限制的想法,请告诉我们!

这是如何工作的?

有两个阶段:打包和执行。

打包阶段 由项目开发者执行,仅在分发之前执行一次。这是一个简单的步骤,开发者运行 PyEmpaq 并指定所有必要信息,PyEmpaq 将生成一个单一的 <projectname>.pyz 文件。就是这样,这就是分发所需的所有文件。

在这个打包阶段,PyEmpaq 构建指定的打包文件,其中包含

  • 有效载荷项目,包含所有指定的模块和二进制文件

  • PyEmpaq 的一个 解包器 脚本,在执行阶段将被运行

  • 一些其他东西:一些必要的详细基础设施,以便 .pyz 正确运行

打包后,开发者将分发打包文件,最终用户将下载/接收/获取它,并执行它。

执行阶段,最终用户需要做的就是使用 Python 运行它,这可以通过命令行完成(例如 python3 supergame.pyz)或通过在将 .pyz 扩展名关联到 Python 的系统(例如 Windows)中双击文件资源管理器来完成。

在这个执行阶段,PyEmpaq 放置在打包文件中的 解包器 脚本将被运行,执行以下步骤

  • 检查是否需要从之前的运行设置;如果是,它将仅运行有效载荷项目,几乎不需要额外的工作;否则...

  • 在用户数据目录(或指定的目录)中创建一个目录,并将 .pyz 文件展开到那里

  • 在该新目录中创建一个虚拟环境,并安装所有有效载荷项目的依赖项

  • 在虚拟环境中运行有效载荷项目

解包器进行的验证,以查看是否有可重用的旧设置,是基于 .pyz 时间戳;如果它已更改(分发了一个新文件),将创建一个新的设置并使用。

可以使用环境变量 PYEMPAQ_UNPACK_BASE_PATH 来指定 PyEmpaq 将在不同项目中将它们解包的基础目录。如果指定,该路径必须存在并且是一个目录。

PyEmpaq 无缝返回有效载荷的退出代码,除非它必须在执行有效载荷之前退出。在这种情况下,它使用特殊代码,等于或大于 64,这意味着

  • 64:最终用户系统上未满足 unpack-restrictions
  • 65:指定的 PYEMPAQ_UNPACK_BASE_PATH 不存在
  • 66:指定的 PYEMPAQ_UNPACK_BASE_PATH 不是一个目录
  • 67:指定的 PYEMPAQ_ACTION 无效

特殊操作

在运行打包项目时,可以通过环境变量 PYEMPAQ_ACTION 来指示一些特殊操作。注意,如果指定了该变量,则会执行特殊操作,而打包程序本身将 不会 运行。

当前特殊操作

  • info:显示指定项目的安装信息

  • uninstall:删除指定项目的所有安装

命令行选项

有一个必填参数

  • source:需要指向配置文件或配置文件所在目录(将按默认名称 pyempaq.yaml 进行搜索)。

示例

  • pyempaq .

  • pyempaq /data/project/

  • pyempaq ~/repo/proj/config.yaml

您可以通过添加以下命令行参数来控制日志级别,以控制详细程度

  • -v, --verbose - 显示详细信息,通常仅在诊断问题时才有用。
  • -q, --quiet - 仅跟踪 WARNING 级别和以上的事件。

所有这些,还有一个特殊选项 -V, --version(从 v0.3 版本开始),如果使用它,将只打印版本号并退出。

注意执行阶段,如果您有环境变量 PYEMPAQ_DEBUG=1,它将在执行期间显示 Pyempaq 的日志行。

配置文件

PyEmpaq 需要打包项目的所有信息都来自配置文件,开发人员通常会将该文件放在项目本身中。

以下为 pyempaq.yaml 配置文件的结构

  • name [必填项]:项目的名称。

  • basedir [可选项]:项目的基目录;如果不包含,则默认为配置文件所在位置。

  • exec [必填项]:定义在解包后执行项目信息的部分;它包含不同的子键(一些子键带有†:必须存在这些键中的一个,但只能有一个)

    • script [†]:要运行的 Python 脚本的文件路径;在解包时,PyEmpaq 将执行 python3 SCRIPT

    • module [†]:要调用的模块的名称;在解包时,PyEmpaq 将执行 python3 -m MODULE

    • entrypoint [†]:自由格式,作为字符串列表;在解包时,PyEmpaq 只在开头插入正确的 python3:python3 STR1 STR2 ...

    • default-args [可选项]:传递给脚本/模块/entrypoint 的默认参数(在执行分发 .pyz 时如果没有覆盖)。

  • requirements [可选项]:指向具有可使用 pip 安装依赖项的要求文件的文件路径列表。

  • dependencies [可选项]:直接指定要由 pip 安装而无需要求文件的包的字符串列表。

  • include [可选项,从 v0.3 版本开始]:字符串列表,每个字符串指定一个模式以决定要包含在打包中的文件和目录(见下文);如果不包含,则默认为 ["./**"],这意味着项目中的所有文件和目录。

  • exclude [可选项,从 v0.3 版本开始]:字符串列表,每个字符串指定一个模式以决定要排除在打包之外的文件和目录(见下文)。

  • unpack-restrictions [可选项,从 v0.3 版本开始]:指定在解包期间要验证/执行的不同限制的部分。

    • minimum-python-version [可选项,从 v0.3 版本开始]:指定可以正确运行的最低版本字符串。

所有指定的文件路径必须位于项目内部,必须是相对路径(相对于项目的基目录),除非是 basedir 本身,它可以绝对或相对(相对于配置文件的位置)。

“include”和“exclude”选项都使用与Unix shell相同的规则进行模式匹配,使用*?以及用[]表示的字符范围。此外,**可以匹配任何文件和零个或多个目录。有关更多信息或细微差别,请参阅glob.glob的文档:glob.glob

请注意,最终用户可以通过使用值为逗号分隔的忽略限制名称的PYEMPAQ_IGNORE_RESTRICTIONS环境变量来忽略/绕过任何解包限制。

以下是一些不同的配置文件示例(这些文件是构建之前提到的打包示例所使用的)

正在运行的项目的上下文

在解包阶段运行打包的脚本/模块/ whatever时,它将在具有所需要求/依赖关系的虚拟环境中执行(全新创建并安装或从之前的运行中重用)。

此外,以下环境变量将被设置

  • PYEMPAQ_PYZ_PATH:用户运行的.pyz的绝对路径

如何安装PyEmpaq

直接从PyPI安装

pip install --user --upgrade --ignore-installed pyempaq

如果您有pipx,使用它来安装它非常方便

pipx install pyempaq

如果您有fades,您甚至不需要安装pyempaq,只需运行它即可

fades -d pyempaq -x pyempaq

将来会有更多安装它的方法。如果您希望安装某种安装方法(如果您指定了如何做,可以获得额外加分),请提出问题,谢谢!

尝试打包一个示例项目

PyEmpaq源代码包含一个小型示例项目,如果您想尝试打包,请访问它。只需在examples/srcproject下有几个目录/文件

  • 一个src和一个media,其中包含要导入和访问的内容。

  • 一个pyempaq.yaml,其中包含PyEmpaq的配置。

  • 一个ep.py文件,它是项目的入口点;它所做的只是通知它已启动,导入内部模块,访问媒体文件,并使用声明的依赖项,报告每一步。

  • 一个secrets.txt文件,该文件不应包含在打包的文件中。

这探索了任何项目的大部分需求。您可以尝试这个示例,并且在之后您将准备好实际打包任何其他项目。

因此,让我们打包示例源项目。由于您正在使用PyEmpaq项目本身(因为您正在打包其示例),您实际上还没有安装它。在这种情况下,如果您已安装fades,则非常简单

fades -r requirements.txt -m pyempaq examples/srcproject/

否则,您需要创建并使用一个虚拟环境

python3 -m venv env
source env/bin/activate
pip install -r requirements
python3 -m pyempaq examples/srcproject/

运行该命令后,您将看到pyempaq-example.pyz文件。这就是将整个项目编码到单个文件中的pyempaq-example.pyz

此时,您可以将其移动到另一个目录,或移动到另一台机器,即使是另一台操作系统。

然后尝试它

python3 pyempaq-example.pyz

您应该看到我们之前提到的项目的报告(注意:这些行将被调试行包围,这些调试行将在未来默认隐藏)

Hello world
Code access ok .../pyempaq/projectname-20210722013526/orig/src/foo.py
Media access ok
Module requests imported .../pyempaq/projectname-20210722013526/venv/lib/python3.8/site-packages/requests/__init__.py

这表明您运行的实际内容已启动,访问了内部模块和其他文件,并正确导入了一个自定义安装的依赖项。

PyEmpaq与其他类似工具的关系

还有其他类似工作的工具。更知名的是ShivPex

Shiv将创建一个包含所有依赖项的完全自包含的Python zip应用程序,这意味着它不仅包含您的项目,还包含其依赖项!这使得生成的.pyz不是多平台的(除非您的项目和所有依赖项都是纯Python...)。

另一方面,PyEmpaq在目标机器上第一次执行.pyz文件时,会创建virtualenv并安装所需的依赖。这允许例如打包一个完全图形化的桌面程序,比如上面展示的例子。

这一过程的细节之一是,我们通常在程序中包含依赖,而这些依赖又可能有子依赖等。你有多确定整个依赖和子依赖集都有允许你分发的许可证?Shiv会分发它们,而PyEmpaq不会!

Pex看起来也会在结果文件中包含依赖,但更进一步的是指明了构建此内容的Python版本。例如,我用Py3.10构建了一个.pex文件,并将其移动到只有3.9的机器上,但它没有工作,而且两者都是Ubuntu!根本就没有多平台,甚至没有提到打包在Linux(一次!)并在Windows(或任何地方)运行,就像PyEmpaq允许的那样。

这两个工具都是“提前”密集(体积较大)的归档,包含针对单一目标平台的应用程序代码和依赖。加密和确定的安装。这也是如果你snap你的项目时可以获得的东西。

另一方面,PyEmpaq是一个稀疏(体积较小)的归档。它仅包含应用程序代码,并在首次运行时创建并安装其余部分到虚拟env中。有点像使用pipx安装应用程序,但不需要教会最终用户关于pipx。它是自安装的。非加密和非确定性的安装,但在实际中可能并不重要。

如何为项目做出贡献?

请查看如何贡献说明

项目详情


下载文件

下载适用于您的平台的文件。如果您不确定要选择哪个,请了解更多关于安装包的信息。

源代码分发

pyempaq-0.6.0.tar.gz (35.1 kB 查看哈希值)

上传时间: 源代码

构建分发

pyempaq-0.6.0-py3-none-any.whl (31.8 kB 查看哈希值)

上传时间: Python 3

由以下赞助

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF 赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误日志 StatusPage StatusPage 状态页面