PIP的要求.txt最佳实践



我正在尝试为某人生成requirements.txt以复制我的环境。正如你所知,标准的方法是

pip freeze > requirements.txt

我注意到,这将列出所有包,包括已安装包的依赖项,这使得这个列表变得不必要。然后我浏览了一下,发现pip-chill只允许我们列出requirements.txt中已安装的软件包。

现在,根据我的理解,当有人试图用pip install -r requirements.txt复制环境时,这将自动安装已安装包的依赖项。

如果这是真的,这意味着使用pip-chill而不是pip来生成requirements.txt是安全的。我的问题是,使用pip-chill省略已安装程序包的依赖项是否还有其他风险,而我在这里缺少这些风险?

我相信在构建requirements.txt时,使用pip工具中的pip-compile是一种很好的做法。这将确保构建是可预测的和确定性的。

pip-compile命令允许您根据在setup.pyrequirements.in中指定的依赖项编译requirements.txt文件

以下是我建议的构建requirements.txt的步骤(如果使用requirements.in(:

  1. 创建一个虚拟环境并在那里安装pip工具
$ source /path/to/venv/bin/activate
(venv)$ python -m pip install pip-tools
  1. 在文件中指定应用程序/项目的直接依赖项您的需求:
# requirements.in
requests
boto3==1.16.51
  1. 使用pipcompile生成requirements.txt
$ pip-compile --output-file=- > requirements.txt

您的requirements.txt文件将包含:

#
# This file is autogenerated by pip-compile
# To update, run:
#
#    pip-compile --output-file=-
#
boto3==1.16.51
# via -r requirements.in
botocore==1.19.51
# via
#   boto3
#   s3transfer
certifi==2020.12.5
# via requests
chardet==4.0.0
# via requests
idna==2.10
# via requests
jmespath==0.10.0
# via
#   boto3
#   botocore
python-dateutil==2.8.1
# via botocore
requests==2.25.1
# via -r requirements.in
s3transfer==0.3.3
# via boto3
six==1.15.0
# via python-dateutil
urllib3==1.26.2
# via
#   botocore
#   requests

您的应用程序应该始终使用从生成的requirements.txt安装的依赖项。如果必须更新依赖项,则只需要更新requirements.in文件并重做pip-compile。我相信这是一个比pip freeze > requirements.txt更好的方法,我看到有些人这样做

我想使用它的主要优点是可以在单独的requirement.in文件中跟踪项目的实际直接依赖关系

我发现这和package.json(requirements.in(和package-lock.json(requirements.txt(的节点应用程序项目中管理节点模块/依赖关系的方式非常相似

从我的角度来看,requirements.txt文件应该列出所有依赖项、直接依赖项及其依赖项(间接、瞬态(。如果出于某种原因,只需要直接依赖项,那么有一些工具可以帮助实现这一点,粗略地看,pip-chill似乎不够,因为它实际上并没有查看代码来确定直接导入了哪些包。也许最好看看pipreqs、pigar等项目,它们似乎更准确地计算出实际的直接依赖关系(基于代码中的导入(。

但在一天结束的时候,你应该手工整理这样的清单。在编写代码时,您要仔细选择要导入的包,同时也要精心策划包含这些包的项目(及其版本(的列表。工具可以提供帮助,但开发人员更清楚。

最新更新