pip requirement.txt条件或基于env变量的环境标记

时间:2016-02-12 01:49:52

标签: python pip requirements.txt

有没有办法在pip requirements.txt文件中指定基于环境变量值的条件安装?

我已经能够通过环境标记控制我需要的大部分内容,但我所知道的所有标记只能使用基本上由python预定义的特定值。

例如,我希望能够控制RHEL 5.3与RHEL 6.3与RHEL 6.6等的软件包安装。还基于其他标准。

如果我可以在results.txt文件中指定一个环境变量,它将根据我在运行pip之前设置的值进行检查,那将是完美的。这似乎是理想和直接的功能。到目前为止,我还没有找到关于环境标记的全面讨论,所以我希望我只是错过了一些关键信息: - )

非常感谢。

2 个答案:

答案 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.txtrequirements.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)