如何使用诗歌将 Python 轮子打包为 cli 可执行文件?

Phi*_*ert 6 python command-line-interface python-wheel python-poetry

问题

\n

我想使用诗歌分发一个 python 包并使其作为 cli 可执行,就像black, pipenv, poetry,flake8朋友一样。

\n

示例用法如下:

\n
python -m my-package [args]\n
Run Code Online (Sandbox Code Playgroud)\n

配置

\n

到目前为止,我已经成功构建了一个轮子并使用以下配置将其安装在 docker 映像上:

\n

pyproject.toml

\n
[tool.poetry]\nname = "my-package\nversion = "0.1.0"\ndescription = "A cli tool"\nauthors = []\npackages = [\n    { include = "src/main.py" },\n]\n\n[build-system]\nrequires = ["poetry-core>=1.0.0"]\nbuild-backend = "poetry.core.masonry.api"\n
Run Code Online (Sandbox Code Playgroud)\n

构建命令:

\n
poetry build -f wheel\npoetry export -o dist/requirements.txt\n
Run Code Online (Sandbox Code Playgroud)\n

Docker 镜像:

\n
FROM python:3.8-slim as base\n\nCOPY dist/requirements.txt /requirements.txt\nRUN pip install --no-cache-dir --upgrade -r /requirements.txt\nARG APP_VERSION\nCOPY dist/my-package-$APP_VERSION-py3-none-any.whl .\nRUN pip install --no-cache-dir --no-deps my-package-$APP_VERSION-py3-none-any.whl\n
Run Code Online (Sandbox Code Playgroud)\n

使用以下命令构建:

\n
docker build -t my-package:latest --build-arg APP_VERSION=$(poetry version -s) .\n
Run Code Online (Sandbox Code Playgroud)\n

并使用以下命令运行:

\n
docker run -it my-package:latest /usr/local/bin/python -m my-package\n
Run Code Online (Sandbox Code Playgroud)\n

结果是:

\n
/usr/local/bin/python: No module named my-package\n
Run Code Online (Sandbox Code Playgroud)\n

在本地,我可以通过执行以下操作来执行它:

\n
cd src\npython main.py [args]\n
Run Code Online (Sandbox Code Playgroud)\n

结论性问题

\n

如何安装/打包一个wheel以使其作为cli可执行?

\n

编辑

\n

附加日志:

\n
\xe2\x95\xb0\xe2\x94\x80 docker build -t my-package:latest --build-arg APP_VERSION=0.1.0 .\n[+] Building 1.9s (10/10) FINISHED                                                                                                                                                                                   \n => [internal] load build definition from Dockerfile                                                                        0.0s\n => => transferring dockerfile: 353B                                                                                        0.0s\n => [internal] load .dockerignore                                                                                           0.0s\n => => transferring context: 2B                                                                                             0.0s\n => [internal] load metadata for docker.io/library/python:3.8-slim                                                          0.9s\n => [1/5] FROM docker.io/library/python:3.8-slim@sha256:0f6d6953c6612786ed05aaf1de7151dbbb0cea6bc83687040d5f15377be7ef64    0.0s\n => [internal] load build context                                                                                           0.0s\n => => transferring context: 6.12kB                                                                                         0.0s\n => CACHED [2/5] COPY dist/requirements.txt /requirements.txt                                                               0.0s\n => CACHED [3/5] RUN pip install --no-cache-dir --upgrade -r /requirements.txt                                              0.0s\n => CACHED [4/5] COPY dist/my-package-0.1.0-py3-none-any.whl .                                                              0.0s\n => [5/5] RUN pip install --user --no-cache-dir --no-deps my-package-0.1.0-py3-none-any.whl                                 0.9s\n => exporting to image                                                                                                      0.0s\n => => exporting layers                                                                                                     0.0s\n => => writing image sha256:4f41ba75b6bbacd33d64a06eed921c1ca8aeca55e9340536b9208fcb694826dd                                0.0s \n => => naming to my-package:latest                                                                                          0.0s\n\nUse 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them\n'package' took 2.9720 sec\n\n\n\xe2\x95\xb0\xe2\x94\x80 docker run -it my-package:latest /bin/bash\nroot@f61d2505e762:/# python -m  my-package\n/usr/local/bin/python: No module named  my-package\nroot@f61d2505e762:/# python -m my-package\n/usr/local/bin/python: No module named my-package\nroot@f61d2505e762:/# pip freeze > req.txt\nroot@f61d2505e762:/# cat req.txt\ncertifi==2021.10.8\ncharset-normalizer==2.0.9\nidna==3.3\nmy-package @ file:///my-package-0.1.0-py3-none-any.whl\npsycopg2-binary==2.9.2\nrequests==2.26.0\nurllib3==1.26.7\n
Run Code Online (Sandbox Code Playgroud)\n

fin*_*mer 4

python -m app与使用命令相比,通过使用不同的机制运行 python 应用程序app

\n

让我们假设以下项目结构:

\n
demo-cli\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 demo_cli\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 __init__.py\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 __main__.py\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 cli.py\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 poetry.lock\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 pyproject.toml\n
Run Code Online (Sandbox Code Playgroud)\n

pyproject.toml:

\n
[tool.poetry]\nname = "demo-cli"\nversion = "0.1.0"\ndescription = ""\nauthors = ["finswimmer <finswimmer77@gmail.com>"]\npackages = [{include = "demo_cli"}]\n\n[tool.poetry.dependencies]\npython = "^3.10"\n\n[tool.poetry.scripts]\ndemo-cli = "demo_cli.cli:say_hello"\n\n[build-system]\nrequires = ["poetry-core"]\nbuild-backend = "poetry.core.masonry.api"\n
Run Code Online (Sandbox Code Playgroud)\n

cli.py:

\n
demo-cli\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 demo_cli\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 __init__.py\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 __main__.py\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 cli.py\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 poetry.lock\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 pyproject.toml\n
Run Code Online (Sandbox Code Playgroud)\n

__main__.py:

\n
[tool.poetry]\nname = "demo-cli"\nversion = "0.1.0"\ndescription = ""\nauthors = ["finswimmer <finswimmer77@gmail.com>"]\npackages = [{include = "demo_cli"}]\n\n[tool.poetry.dependencies]\npython = "^3.10"\n\n[tool.poetry.scripts]\ndemo-cli = "demo_cli.cli:say_hello"\n\n[build-system]\nrequires = ["poetry-core"]\nbuild-backend = "poetry.core.masonry.api"\n
Run Code Online (Sandbox Code Playgroud)\n

这部分通过定义应该执行的方法pyproject.toml给我们一个命令:demo-cli

\n
[tool.poetry.scripts]\ndemo-cli = "demo_cli.cli:say_hello"\n
Run Code Online (Sandbox Code Playgroud)\n

的内容__main__.py在 上触发python -m demo_cli。所以我们需要在那里添加方法调用。更详细的信息可以从这里找到。

\n