Rumah > pembangunan bahagian belakang > Tutorial Python > pex: Membungkus fail boleh laku Python

pex: Membungkus fail boleh laku Python

WBOY
Lepaskan: 2023-08-26 14:49:10
asal
1716 orang telah melayarinya

pex:打包 Python 可执行文件

pex adalah singkatan kepada Python EXecutable dan merupakan satu cara untuk menjana pakej python yang mudah untuk diedarkan. Satu perkara penting untuk diperhatikan ialah pex tidak mempunyai sokongan Windows yang kukuh. Oleh itu, anda perlu menjalankan pex pada sistem *NIX. Artikel ini akan menunjukkan kepada anda beberapa perkara yang boleh anda lakukan dengan pex untuk mengedarkan pelbagai jenis projek python.

Penggunaan asas

Memandangkan kepentingan penterjemah python untuk pembungkusan pex, adalah sangat disyorkan untuk menggunakan persekitaran maya. Sebagai contoh saya akan menggunakan persekitaran 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
Salin selepas log masuk
Masukkan mod skrin penuh Keluar daripada mod skrin penuh

Format umum pelaksanaan pex CLI ialah:

pex [模块] [选项]

di mana [MODULES] ialah senarai modul yang diasingkan ruang dalam rentetan perisytiharan pergantungan gaya 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)
>>>
Salin selepas log masuk
Masukkan mod skrin penuh Keluar daripada mod skrin penuh

Tanpa pilihan lain, pex akan memasuki shell interaktif dan modul yang disediakan akan tersedia di:

>>> import requests
>>> import setproctitle
>>> import uvicorn
>>> 
Salin selepas log masuk
Masukkan mod skrin penuh Keluar daripada mod skrin penuh

Selepas menutup konsol, kita dapat melihat bahawa pakej persekitaran maya tidak terjejas sama sekali:

$ pip list
Package    Version
---------- -------
pex        2.1.144
pip        23.2.1
setuptools 65.5.0
$
Salin selepas log masuk
Masukkan mod skrin penuh Keluar daripada mod skrin penuh

Pengurusan permintaan

Memandangkan penyenaraian setiap modul biasanya tidak sesuai, terdapat dua cara alternatif untuk menyampaikan keperluan. Penyelesaian pertama ialah menggunakan fail requirements.txt:

requirements.txt

requests
setproctitle==1.3.2
uvicorn[standard]
Salin selepas log masuk
Masukkan mod skrin penuh Keluar daripada mod skrin penuh

pex kemudiannya boleh dijalankan menggunakan pilihan -r dan fail yang diluluskan dalam requirements.txt:

$ 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)
>>> 
Salin selepas log masuk
进入全屏模式 退出全屏模式

-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)
>>>
Salin selepas log masuk
进入全屏模式 退出全屏模式

如果您有很多模块需要使用,则 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
>>>
Salin selepas log masuk
进入全屏模式 退出全屏模式

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

资源目录

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

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

我们可以使用 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
>>> 
Salin selepas log masuk
进入全屏模式 退出全屏模式

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

切入点

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

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

这将生成一个名为“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)
Salin selepas log masuk
进入全屏模式 退出全屏模式

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

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

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

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

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

Docker 部署

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

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

另一件需要考虑的事情是,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"
Salin selepas log masuk
进入全屏模式 退出全屏模式

虽然 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
Salin selepas log masuk
进入全屏模式 退出全屏模式

鉴于我构建 .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
Salin selepas log masuk
进入全屏模式 退出全屏模式

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

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

感谢 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
Salin selepas log masuk
进入全屏模式 退出全屏模式

这使得更容易辨别容器上的各种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
Salin selepas log masuk
进入全屏模式 退出全屏模式

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
Salin selepas log masuk
进入全屏模式 退出全屏模式

这将分离依赖项和源编译。当 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
Salin selepas log masuk
进入全屏模式 退出全屏模式

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

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

缓存文件也会早于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
Salin selepas log masuk
进入全屏模式 退出全屏模式

结论

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

Atas ialah kandungan terperinci pex: Membungkus fail boleh laku Python. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:php.cn
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan