当前位置:

首页 > 编程开发 > pex:打包 Python 可执行文件

pex:打包 Python 可执行文件

pex代表PythonEXecutable,是一种生成易于分发的python包的方法。需要注意的一件重要事情是pex没有可靠的Windows支持。因此,您需要在*NIX系统上运行pex。本文将展示您可以使用pex执行的一些操作,以分发不同类型的python项目。基本用法鉴于用于pex打包的python解释器很重要,强烈建议使用虚拟环境。作为示例,我将使用python3.11环境:$virtualenv--python=python3.11venv$sourcevenv/bin/activate$pytho

本文目录

    pex 代表 Python EXecutable,是一种生成易于分发的 python 包的方法。需要注意的一件重要事情是 pex 没有可靠的 Windows 支持。因此,您需要在 *NIX 系统上运行 pex。本文将展示您可以使用 pex 执行的一些操作,以分发不同类型的 python 项目。

    基本用法

    鉴于用于 pex 打包的 python 解释器很重要,强烈建议使用虚拟环境。作为示例,我将使用 python 3.11 环境:

    $ virtualenv --python=python3.11 venv
    $ source venv/bin/activate
    $ python -m pip install pex
    Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple
    Collecting pex
      Using cached https://www.piwheels.org/simple/pex/pex-2.1.144-py2.py3-none-any.whl (2.9 MB)
    Installing collected packages: pex
    Successfully installed pex-2.1.144
    
    进入全屏模式 退出全屏模式

    pex CLI 执行的一般格式是:

    pex [模块] [选项]

    其中 [MODULES] 是 pip 样式依赖项声明字符串中的空格分隔的模块列表:

    $ pex "requests" "setproctitle==1.3.2" "uvicorn[standard]"
    Python 3.11.4 (main, Aug 17 2023, 03:18:09) [GCC 10.2.1 20210110] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    (InteractiveConsole)
    >>>
    
    进入全屏模式 退出全屏模式

    如果没有任何其他选项,pex 将进入交互式 shell,并且提供的模块将在以下位置可用:

    >>> import requests
    >>> import setproctitle
    >>> import uvicorn
    >>> 
    
    进入全屏模式 退出全屏模式

    关闭控制台后我们可以看到虚拟环境包完全不受影响:

    $ pip list
    Package    Version
    ---------- -------
    pex        2.1.144
    pip        23.2.1
    setuptools 65.5.0
    $
    
    进入全屏模式 退出全屏模式

    需求管理

    由于列出每个模块通常并不理想,因此可以使用两种替代方法来传递需求。第一个解决方案是使用 requirements.txt 文件:

    requirements.txt

    requests
    setproctitle==1.3.2
    uvicorn[standard]
    
    进入全屏模式 退出全屏模式

    然后可以使用 -r 选项和传入的 requirements.txt 文件运行 pex:

    $ pex -r requirements.txt 
    Python 3.11.4 (main, Aug 17 2023, 03:18:09) [GCC 10.2.1 20210110] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    (InteractiveConsole)
    >>> 
    
    进入全屏模式 退出全屏模式

    -r 参数也可以多次传递,以防您捆绑多个项目。如果您已经设置了虚拟环境,那么您可以将 pip freeze 传递给 pex:

    $ pex $(pip freeze)
    Python 3.11.4 (main, Aug 17 2023, 03:18:09) [GCC 10.2.1 20210110] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    (InteractiveConsole)
    >>>
    
    进入全屏模式 退出全屏模式

    如果您有很多模块需要使用,则 requirements.txt 方法会很好。 pip freeze 对于已经设置了 virtualenv 的情况很有用。

    Python 项目结构化模块

    pex 还支持 python 包作为模块,其结构类似于 python 打包文档中的基本结构。对于此示例,我将使用此 git 存储库中的项目布局。它包括一个带有自述文件、许可证、简单模块和 pyproject.toml 的基本布局。这足以让它被 pex 识别,就像开发模式 pip install 一样:

    $ pex .
    Python 3.11.4 (main, Aug 17 2023, 03:18:09) [GCC 10.2.1 20210110] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    (InteractiveConsole)
    >>> from simple_pex import simple_math
    >>> simple_math(3,4)
    7
    >>>
    
    进入全屏模式 退出全屏模式

    这一切都是在无需构建项目本身的情况下实现的。

    资源目录

    pex 还可以添加测试数据和配置等重要项目的目录。在应用程序存储库中,有一个 resources 目录,其中包含一个 test_data.json 文件,如下所示:

    {
        "a": 1,
        "b": 2
    }
    
    进入全屏模式 退出全屏模式

    我们可以使用 pex 和 -D 参数来添加特定的捆绑目录。然后可以在脚本/交互式提示中使用它,如下所示:

    $ pex . -D resources
    Python 3.11.4 (main, Aug 17 2023, 03:18:09) [GCC 10.2.1 20210110] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    (InteractiveConsole)
    >>> from simple_pex import simple_math
    >>> import json
    >>> fp = open('resources/test_data.json', 'r')
    >>> data = json.load(fp)
    >>> fp.close()
    >>> simple_math(data['a'], data['b'])
    3
    >>> 
    
    进入全屏模式 退出全屏模式

    如您所见,JSON 数据被加载,然后传递给 simple_math 函数,在该函数中返回正确的结果。

    切入点

    Python 脚本的一个功能是能够像运行基本程序一样设置入口点。对于此示例,我将使用此存储库中托管的代码。使这项工作有效的是控制台脚本的声明,如下所示:

    [project.scripts]
    adder = "cli_pex:run"
    
    进入全屏模式 退出全屏模式

    这将生成一个名为“adder”的脚本,该脚本将从 cli_pex 包中执行 run:

    import argparse
    
    def run():
        parser = argparse.ArgumentParser()
        parser.add_argument("--integer1", type=int, help="First Integer")
        parser.add_argument("--integer2", type=int, help="Second Integer")
        args = parser.parse_args()
        print(args.integer1 + args.integer2)
    
    进入全屏模式 退出全屏模式

    虽然不是一个非常实用的程序,但它可以完成展示 pex 如何与控制台脚本一起工作的工作。要展示这一点:

    $ pex . -o adder.pex -c adder
    $ ./adder.pex --integer1 3 --integer2 4
    7
    
    进入全屏模式 退出全屏模式

    使用 -c 告诉 pex 我们要使用 pyproject.toml 中定义的 adder 脚本。现在,当我们打包所有内容时,它就像一个基本程序一样。还有一个使用固定参数的选项,因此只需要执行 .pex 文件:

    $ pex . -o adder.pex -c adder --inject-args "--integer1 3 --integer2 4"
    $ ./adder.pex 
    7
    
    进入全屏模式 退出全屏模式

    这对于轻松部署采用绑定端口和主机名等参数的服务器脚本非常有用。

    Docker 部署

    为了将这一切放在一起,我将对 pex Web 应用程序进行 Docker 部署。它将把 Gunicorn 与 Flask 应用程序捆绑在一起,该应用程序将充当容器的入口点。可以在此处找到此示例中使用的代码。在此设置中,有一个简单的 Flask 应用程序、一个 Gunicorn 配置文件和一个用于启用部署的 Dockerfile。这次 pyproject.toml 声明了一些依赖项:

    dependencies = [
        "flask",
        "gunicorn",
        "setproctitle",
    ]
    
    进入全屏模式 退出全屏模式

    另一件需要考虑的事情是,pex 需要将其打包的系统设置与目标系统相当接近。这意味着我将在 Unbuntu 盒子上构建,而我的容器将基于 Debian(更精简,并且系统足够接近)。其他一些需要完成的事情:

    • pex可执行文件需要指向gunicorn控制台脚本才能运行服务器
    • gunicorn 配置文件需要复制到系统
    • --inject-args 需要将 --config 参数设置为gunicorn配置
    • 生成的 .pex 文件需要设置为入口点

    查看要求,生成的 pex 调用将是:

    pex . -o web_pex.pex -c gunicorn --inject-args "--config /home/gunicorn/app/gunicorn.config.py"
    
    进入全屏模式 退出全屏模式

    虽然 Dockerfile 看起来像:

    FROM python:3.11.4-bullseye
    
    USER root
    RUN useradd -d /home/gunicorn -r -m -U -s /bin/bash gunicorn
    
    USER gunicorn
    RUN mkdir /home/gunicorn/app
    COPY config/gunicorn.config.py /home/gunicorn/app
    COPY web_pex.pex /home/gunicorn/app
    
    ENTRYPOINT /home/gunicorn/app/web_pex.pex
    EXPOSE 8000
    
    进入全屏模式 退出全屏模式

    鉴于我构建 .pex 包的解释器是 python 3.11,我将其设置为基础映像。现在剩下的就是构建 Dockerfile,然后运行生成的映像:

    $ docker buildx build  -f Dockerfile -t flask/web-pex:latest .
    $ docker run -it -p 8000:8000 flask/web-pex:latest
    [2023-08-25 00:13:11 +0000] [7] [INFO] Starting gunicorn 21.2.0
    [2023-08-25 00:13:11 +0000] [7] [INFO] Listening at: http://0.0.0.0:8000 (7)
    [2023-08-25 00:13:11 +0000] [7] [INFO] Using worker: sync
    [2023-08-25 00:13:11 +0000] [8] [INFO] Booting worker with pid: 8
    [2023-08-25 00:13:11 +0000] [9] [INFO] Booting worker with pid: 9
    
    进入全屏模式 退出全屏模式

    这将运行新创建的 flask/web-pex:latest 映像并公开端口 8000。现在使用curl 进行测试:

    $ curl http://127.0.0.1:8000
    Hello World
    
    进入全屏模式 退出全屏模式

    感谢 setproctitle 进程列表也变得更清晰:

    $ ps aux
    USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
    gunicorn       1  0.0  0.0   2480   512 pts/0    Ss+  00:13   0:00 /bin/sh -c /home/gunicorn/app/web_pex.pex
    gunicorn       7  4.5  0.2  53904 48244 pts/0    S+   00:13   0:00 gunicorn: master [gunicorn]
    gunicorn       8  1.1  0.3  63244 52084 pts/0    S+   00:13   0:00 gunicorn: worker [gunicorn]
    gunicorn       9  0.6  0.3  62024 51644 pts/0    S+   00:13   0:00 gunicorn: worker [gunicorn]
    gunicorn      10  0.5  0.0   6052  3784 pts/1    Ss   00:13   0:00 /bin/bash
    gunicorn      17  0.0  0.0   8648  3276 pts/1    R+   00:13   0:00 ps aux
    
    进入全屏模式 退出全屏模式

    这使得更容易辨别容器上的各种gunicorn进程。

    工具

    另一个有趣的功能是 pex 还提供了一些可用的工具,可以让我们创建性能更高的 docker 镜像。为了完成这项工作,我们需要将 --include-tools 添加到 pex 构建命令:

    $ pex . -o web_pex.pex -c gunicorn --inject-args "--config /home/gunicorn/app/gunicorn.config.py" --include-to
    ols
    
    进入全屏模式 退出全屏模式

    Dockerfile 也将更新为多阶段构建以生成最终的映像:

    FROM python:3.11.4-bullseye as deps
    RUN mkdir -p /home/gunicorn/app
    COPY web_pex.pex /home/gunicorn/
    RUN PEX_TOOLS=1 /usr/local/bin/python3.11 /home/gunicorn/web_pex.pex venv --scope=deps --compile /home/gunicorn/app
    
    FROM python:3.11.4-bullseye as srcs
    RUN mkdir -p /home/gunicorn/app
    COPY web_pex.pex /home/gunicorn
    COPY config/gunicorn.config.py /home/gunicorn/app
    RUN PEX_TOOLS=1 /usr/local/bin/python3.11 /home/gunicorn/web_pex.pex venv --scope=srcs --compile /home/gunicorn/app
    
    FROM python:3.11.4-bullseye
    RUN useradd -d /home/gunicorn -r -m -U -s /bin/bash gunicorn
    COPY --from=deps --chown=gunicorn:gunicorn /home/gunicorn/app /home/gunicorn/app
    COPY --from=srcs --chown=gunicorn:gunicorn /home/gunicorn/app /home/gunicorn/app
    USER gunicorn
    ENTRYPOINT /home/gunicorn/app/pex
    EXPOSE 8000
    
    进入全屏模式 退出全屏模式

    这将分离依赖项和源编译。当 python 进行编译时,它将创建一组特定于解释器的字节码,因此不必在运行时完成。这使得事情运行得更快。 docker 构建的唯一变化是 Dockerfile 不同,而运行命令保持不变:

    $ docker buildx build  -f Dockerfile_pex_tools -t flask/web-pex:latest .
    $ docker run -it -p 8000:8000 flask/web-pex:latest
    [2023-08-25 01:25:47 +0000] [7] [INFO] Starting gunicorn 21.2.0
    [2023-08-25 01:25:47 +0000] [7] [INFO] Listening at: http://0.0.0.0:8000 (7)
    [2023-08-25 01:25:47 +0000] [7] [INFO] Using worker: sync
    [2023-08-25 01:25:47 +0000] [8] [INFO] Booting worker with pid: 8
    [2023-08-25 01:25:47 +0000] [9] [INFO] Booting worker with pid: 9
    
    进入全屏模式 退出全屏模式

    查看容器内部,可以看到 gunicorn 用户的 ~/app 目录中 pex 的布局:

    $ cd ~/app
    $ ls
    PEX-INFO  __main__.py  __pycache__  bin  gunicorn.config.py  include  lib  lib64  pex  pyvenv.cfg
    
    进入全屏模式 退出全屏模式

    缓存文件也会早于gunicorn工人生成的时间显示,以表明它们确实是编译输出,而不仅仅是Python自然生成的:

    $ ls -lah lib/python3.11/site-packages/flask/__pycache__/
    total 388K
    drwxr-xr-x 2 gunicorn gunicorn 4.0K Aug 25 01:03 .
    drwxr-xr-x 4 gunicorn gunicorn 4.0K Aug 25 01:03 ..
    -rw-r--r-- 1 gunicorn gunicorn 4.0K Aug 25 01:03 __init__.cpython-311.pyc
    -rw-r--r-- 1 gunicorn gunicorn  249 Aug 25 01:03 __main__.cpython-311.pyc
    -rw-r--r-- 1 gunicorn gunicorn  86K Aug 25 01:03 app.cpython-311.pyc
    -rw-r--r-- 1 gunicorn gunicorn  32K Aug 25 01:03 blueprints.cpython-311.pyc
    
    进入全屏模式 退出全屏模式

    结论

    关于使用 pex 打包 python 代码的介绍到此结束。这是一个有趣的系统,从 GitHub 问题来看也具有可重复构建的潜力。启用工具可以轻松地使用单个包部署,同时通过多阶段编译启用更高性能的选项。我鼓励您看看它如何增强您的 Python 项目。

    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
    作者最新文章
    编程开发
    相关文章 更多
    GitHub六个AI开源项目能做什么?软件理解、语音与求职场景
    GitHub六个AI开源项目能做什么?软件理解、语音与求职场景

    解析六个GitHub AI开源项目的具体用途,包括软件静态分析、智能体回答检查、多语言配音、求职材料生成、本地代码检索及动态歌词展示,帮助开发者根据实际需求筛选工具并正确验证结果。

    opencode安装skills教程及本地配置方法
    opencode安装skills教程及本地配置方法

    遇到OpenCode Skills无法加载或配置无效?本文手把手教你完成Skills的安装、环境变量设置及本地调试,避开常见坑点,让AI助手更懂你的代码习惯。

    如何开启Visual Studio2022实时代码分析警告提示
    如何开启Visual Studio2022实时代码分析警告提示

    解决 Visual Studio 2022 编辑时不显示代码分析警告的问题。指南涵盖 .NET 项目实时分析设置、Roslyn 分析器范围调整及错误列表来源筛选,确保开发者能高效利用实时代码诊断功能。

    如何在Visual Studio2022查看变量监视窗口调试程序
    如何在Visual Studio2022查看变量监视窗口调试程序

    详解 Visual Studio 2022 调试技巧:包括断点设置、监视窗口开启方法、变量添加步骤以及通过 F10 单步执行观察变量值变化的全过程。

    Visual Studio2017设置默认编码为UTF-8不带BOM
    Visual Studio2017设置默认编码为UTF-8不带BOM

    针对 Visual Studio 2017 缺乏全局默认编码选项的情况,详解如何利用 .editorconfig 设定项目级 UTF-8 无 BOM 规则,以及手动转换现有文件并校验字节的方法。

    Visual Studio2022F5调试提示启动项目未配置怎么修复
    Visual Studio2022F5调试提示启动项目未配置怎么修复

    解决 Visual Studio 2022 F5 调试报错问题,通过设置启动项目、检查解决方案属性及正确区分类库与应用项目,快速恢复调试功能。

    Visual Studio2022NuGet包还原失败离线处理方案
    Visual Studio2022NuGet包还原失败离线处理方案

    解决Visual Studio 2022离线环境中NuGet包还原失败的难题,涵盖依赖链分析、本地源配置、包集收集及隔离验证步骤,帮助开发者构建稳定的离线开发环境。

    Visual Studio2017大项目加载缓慢,优化加载性能技巧
    Visual Studio2017大项目加载缓慢,优化加载性能技巧

    解决Visual Studio 2017大型项目加载慢的实用指南。涵盖性能监测、扩展管理、文档恢复优化及版本兼容性检查,帮助开发者精准定位瓶颈并提升工作效率。

    Visual Studio2022设置多启动项目同时调试运行
    Visual Studio2022设置多启动项目同时调试运行

    详解 Visual Studio 2022 多启动项目配置方法,包括启动动作选择、顺序调整及调试技巧,帮助开发者高效调试分布式或前后端分离应用。

    fastapi下载文件接口实现教程
    fastapi下载文件接口实现教程

    深入解析在FastAPI框架中实现文件下载接口的完整方案,涵盖基于FileResponse的本地静态文件传输、基于StreamingResponse的分块流式传输、RFC 5987中文文件名编码规范、路径穿越安全防御及BackgroundTasks临时文件清理,并配备详细代码示例与架构解析图。

    查看更多
    精品专题 更多
    装机必备
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows
    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    PDF教程
    PDF教程

    正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

    Mac软件 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    Aperty macOS版
    Aperty macOS版
    macOS

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    WINDOWS 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    PixTV 网页版
    PixTV 网页版
    Windows

    PixTV 是一款在浏览器中使用的 AI 视觉内容创作平台,提供图片、视频、音频、文字生成、AI 分镜、局部重绘、提示词反推和无限画布等工具,适合短剧、漫剧、广告及社交媒体内容制作。