在conda虚拟环境中创建符合pip格式的requirements.txt文件

18

我在Windows 10上创建了一个conda虚拟环境来开展项目工作。为了安装所需的软件包和依赖项,我使用conda install <package>而不是pip install <package>,这符合最佳实践

为了发布我的软件,我选择创建一个environment.yml和一个requirements.txt文件,以针对conda用户和非conda用户。我能够将当前虚拟环境导出为yml文件,因此可以满足conda用户的需求。但是,为了让非conda用户能够复制相同的环境,我需要创建并共享requirements.txt文件。这个文件可以使用conda list --export > requirements.txt创建,但这种格式与pip不兼容,其他用户无法在其系统上使用pip install -r requirements.txt

使用pip freeze > requiremens.txt这里这里提到的解决方案。这意味着非conda用户可以在虚拟环境中执行pip install -r requirements.txt,而在缺乏conda的情况下,他们可以使用virtualenv创建虚拟环境。

但是,如果按照上述方式生成一个requiremets.txt文件,则最终得到的requirements.txt文件将具有符号链接。这是因为我们尝试创建针对使用conda install而不是pip install安装的软件包的requirements.txt文件。 例如,我以类似的方式生成的requirements.txt文件如下所示:

certifi==2020.6.20
cycler==0.10.0
kiwisolver==1.2.0
matplotlib @ file:///C:/ci/matplotlib-base_1603355780617/work
mkl-fft==1.2.0
mkl-random==1.1.1
mkl-service==2.3.0
numpy @ file:///C:/ci/numpy_and_numpy_base_1596215850360/work
olefile==0.46
pandas @ file:///C:/ci/pandas_1602083338010/work
Pillow @ file:///C:/ci/pillow_1602770972588/work
pyparsing==2.4.7
python-dateutil==2.8.1
pytz==2020.1
sip==4.19.13
six==1.15.0
tornado==6.0.4
wincertstore==0.2

当使用此文件安装依赖项时,这些符号链接将导致错误。

我采取的步骤导致了上述 requirements.txt 文件:

  1. 使用 conda create -n myenv python=3.8 创建了一个新的 conda 虚拟环境
  2. 使用 conda activate myenv 激活了新创建的 conda 虚拟环境
  3. 使用 conda install pip 安装了 pip
  4. 使用 conda install pandas 安装了 pandas
  5. 使用 conda install matplotlib 安装了 matplotlib
  6. 使用 pip freeze > requirements.txt 生成了一个兼容 pip 的 requirements.txt 文件

所以,我的问题是如何遵循使用 conda install 而不是 pip install 的最佳实践,同时仍能将软件包分发给 conda 和非 conda 用户?

3个回答

38

对于上述问题,我发现最好的解决方案是下面我将要描述的组合。对于conda,我会首先将环境列表导出为environment.yml文件,并省略软件包的构建编号,因为这常常是在另一个操作系统上重现环境变得困难的原因:

conda env export > environment.yml --no-builds

输出:

name: myenv
channels:
  - defaults
  - conda-forge
dependencies:
  - blas=1.0
  - ca-certificates=2020.10.14
  - certifi=2020.6.20
...
对于pip而言,您上面描述的显然是pip更近版本中一个众所周知的问题。获取一个“干净”的requirements.txt文件的解决方法是将其导出为:
pip list --format=freeze > requirements.txt

输出:

certifi==2020.6.20
cycler==0.10.0
kiwisolver==1.2.0
matplotlib==3.3.2
mkl-fft==1.2.0
...

请注意,上述内容在pipconda之间存在区别,这很可能是因为condapip更通用,并且不仅包括Python软件包。

就我个人而言,我发现为了分发一个软件包,最好通过检查代码(你导入了什么?)来确定所需的最小软件包集及其版本,而不是盲目地导出完整的pipconda列表,这可能会(无意或有意地)包括并非真正需要使用软件包的软件包。


1
感谢您的回答!@tania。使用--format=freeze标志创建的requirements.txt确实是干净的版本,即没有符号链接。这个答案也有助于理解两者之间的区别以及在这种情况下需要考虑的关键事项。 - user14477880
3
@tania,我写了一个包,正如你在最后描述的那样。https://anaconda.org/jamespreed/conda-minify 它使用有向无环图来查找所有其他包可以作为依赖项派生的顶级包。 - James
@James 真是太棒了!:D 一定会去看看的。 - tania

1

在您的bash shell上,您可以简单地运行以下命令:

conda list | awk {'print $1'} |sed '/#/d;/_/d'> requirements.txt

在上面的代码中,我只是获取依赖项名称并从文件中删除以#_开头的行。这将不包括任何依赖项的版本。 *这可以作为bash脚本运行。


1

pip freeze 命令会返回环境中所有已安装的包。

使用 pipreqs 命令可以根据导入情况,包含应用程序所需的包。

示例

pip install pipreqs

安装完成后,请执行以下操作。
pipreqs /home/project/location
Successfully saved requirements file in /home/project/location/requirements.txt

生成的requirements.txt文件:

wheel==0.23.0
Yarg==0.1.9
docopt==0.6.2

请查看文档以获取更多信息。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接