有没有办法在pip requirements.txt文件中指定基于环境变量值的条件安装?
我已经能够通过环境标记控制我需要的大部分内容,但我所知道的所有标记只能使用基本上由python预定义的特定值。
例如,我希望能够控制RHEL 5.3与RHEL 6.3与RHEL 6.6等的软件包安装。还基于其他标准。
如果我可以在results.txt文件中指定一个环境变量,它将根据我在运行pip之前设置的值进行检查,那将是完美的。这似乎是理想和直接的功能。到目前为止,我还没有找到关于环境标记的全面讨论,所以我希望我只是错过了一些关键信息: - )
非常感谢。
答案 0 :(得分:3)
使用环境变量实际上并没有办法。 Pip需求文件基本上只是文件中列出的pip install
参数列表。因此,如果您的需求文件如下所示:
Foo==1.1.0
Bar==0.1.0
Baz==2.0.1
逻辑上,pip正在这样做:
pip install Foo==1.1.0
pip install Bar==0.1.0
pip install Baz==2.0.1
不幸的是,在这种情况下,无法应用环境变量。
这个问题有几个解决方案。
首先,你可以有一个基本要求文件,比如说requirements.txt
,它列出了所有平台的常见依赖关系。然后,您可以拥有名称为requirements.rhel53.txt
,requirements.rhel63.txt
等的单个需求文件。每个文件的顶部可以将此作为第一行:
-r requirements.txt
然后列出其他特殊依赖项。然后,在每个环境中,您可以设置一个env var,让我们调用它$PLATFORM
,并运行这样的命令来安装依赖项:
$ pip install -r requirements.$PLATFORM.txt
或者,您可以使用constraints files。您的requirements.txt
只列出没有版本的依赖项:
Foo
Bar
Baz
然后你可以为每个平台提供一个约束文件,列出特定的版本要求。例如,你可以constraints.rhel53.txt
拥有这个:
Foo==1.1.0
Bar==0.1.0
Baz==2.0.1
再次,你设置一个env var然后运行这样的命令:
$ pip install -r requirements.txt -c constraints.$PLATFORM.txt
这是一个麻烦的解决方案,但这将是解决它的一种方法。不幸的是,pip没有原生解决方案。
答案 1 :(得分:0)
我最终得到了一个脚本化的解决方案,类似于我发现的解决方案: Is there a way to have a conditional requirements.txt file for my Python application based on platform?
基本上,我做了类似下面(部分)示例的操作,它允许我根据需要在脚本中定义包,并且仍然传递requirements.txt和constraints.txt文件。我是Python的新手,所以请原谅(或评论)任何不太理想的编码实践:
import pip, sys, getopt
def install(options, packages):
pipargs = options + packages
pip.main(pipargs)
constraints_file = ''
requirements_file = ''
try:
opts, args = getopt.getopt(sys.argv[1:],"hr:c:",["help","requirements-file=","constraints-file="])
except getopt.GetoptError:
print_usage()
sys.exit(2)
for opt, arg in opts:
if opt in ("-h", "--help"):
print_usage()
sys.exit()
elif opt in ("-r", "--requirements-file"):
requirements_file = arg
elif opt in ("-c", "--constraints-file"):
constraints_file = arg
base_pkgs = [
"nose>=1.3.4",
"wheel",
"pytz"
]
foo_pkgs = [
"Pygments; python_version == '2.7'",
"rednose; python_version == '3.5'",
]
bar_pkgs = [
"six",
]
if __name__ == '__main__':
from os import environ as env
myvar = env.get('MYVAR')
if(myvar == 'foo'):
mypkgs = foo_pkgs
elif(myvar == 'bar'):
mypkgs = bar_pkgs
else:
mypkgs = ''
pkglist = base_pkgs + mypkgs
pipoptions = [ 'install',
'--upgrade',
'--force-reinstall'
]
if(constraints_file):
pipoptions += ['-c', constraints_file]
if(requirements_file):
pipoptions += ['-r', requirements_file]
install(pipoptions, pkglist)