打包具有依赖项的 python 项目的标准方法是什么?

打包具有依赖项的 python 项目的标准方法是什么?

问题描述:

我有一个 python 项目,它有一些依赖项(在 setup.py 中的 install_requires 下定义).我的操作人员需要一个独立的包,并且只依赖于 python 安装.试金石是他们能够获得一个 zip 文件,然后在没有互联网连接的情况下解压并运行它.

I have a python project that has a few dependencies (defined under install_requires in setup.py). My ops people requires a package to be self contained and only depend on a python installation. The litmus test would be that they're able to get a zip-file and then unzip and run it without an internet connection.

是否有一种简单的方法可以打包包含依赖项的安装?如果我必须在它最终运行的操作系统/架构上进行构建,这是可以接受的.

Is there an easy way to package an install including dependencies? It is acceptable if I have to build on the OS/architecture that it will eventually be run on.

就其价值而言,我已经尝试了 setup.py buildsetup.py sdist,但它们似乎不符合要求,因为它们确实符合要求不包括依赖项.我也考虑过 virtualenv(如果绝对必要,可以安装它),但它有硬编码路径,这使它不太理想.

For what it's worth, I've tried both setup.py build and setup.py sdist, but they don't seem to fit the bill since they do not include dependencies. I've also considered virtualenv (which could be installed if absolutely necessary), but that has hard coded paths which makes it less than ideal.

pip 的工作方式有一些细微差别.不幸的是,如果这些依赖项中的任何一个或依赖项的依赖项安装到 pip 可以找到它们的位置,则使用 --prefix vendor 来存储项目的所有依赖项将不起作用.它将跳过这些依赖项,并将其余的安装到您的 vendor 文件夹中.

There are a few nuances to how pip works. Unfortunately, using --prefix vendor to store all the dependencies of the project doesn't work if any of those dependencies, or dependencies of dependencies are installed into a place where pip can find them. It will skip those dependencies and just install the rest to your vendor folder.

过去我使用 virtualenv 的 --no-site-packages 选项来解决这个问题.在一家公司,我们会发布整个 virtualenv,其中包括 python 二进制文件.为了仅传送依赖项,您可以将 virtualenv 与 pip 上的 --prefix 开关结合使用,为自己提供一个安装到正确位置的干净环境.

In the past I've used virtualenv's --no-site-packages option to solve this issue. At one company we would ship the whole virtualenv, which includes the python binary. In the interest of only shipping the dependencies, you can combine using a virtualenv with the --prefix switch on pip to give yourself a clean environment that installs to the right place.

我将提供一个示例脚本,用于创建临时 virtualenv,激活它,然后将依赖项安装到本地 vendor 文件夹.如果您在 CI 中运行,这很方便.

I'll provide an example script that creates a temporary virtualenv, activates it, then installs the dependencies to a local vendor folder. This is handy if you are running in CI.

#!/bin/bash

tempdir=$(mktemp -d -t project.XXX) # create a temporary directory
trap "rm -rf $tempdir" EXIT         # ensure it is cleaned up
# create the virtualenv and exclude packages outside of it
virtualenv --python=$(which python2.7) --no-site-packages $tempdir/venv
# activate the virtualenv
source $tempdir/venv/bin/activate    
# install the dependencies as above
pip install -r requirements.txt --prefix=vendor