pip requirement.txt conditionals or environment markers based on env variables

Deadly 提交于 2020-04-13 06:44:09

问题


Is there a way to specify conditional installs in a pip requirements.txt file that are based on the value of an environment variable?

I've been able to control most of what I need with environment markers, but all the markers I know of work only with specific values that are essentially pre-defined by python.

For example, I want to be able to control package installation for RHEL 5.3 vs. RHEL 6.3 vs. RHEL 6.6, etc. Also based on other criteria.

It would be perfect if I could specify in the results.txt file an environment variable that would be checked against a value I set before running pip. This seems like it would be desirable and straight forward functionality. I haven't had much luck so far finding comprehensive discussions of environment markers, so I'm hoping I've just missed some key bit of information :-)

Thanks much.


回答1:


There's not really a way to do it with environment variables. Pip requirements files are basically just a list of pip install arguments listed in a file. So if your requirements file looks like this:

Foo==1.1.0
Bar==0.1.0
Baz==2.0.1

Logically, pip is doing this:

pip install Foo==1.1.0
pip install Bar==0.1.0
pip install Baz==2.0.1

Unfortunately, in that context there's no way to apply environment variables.

There are a couple solutions to this problem.

One, you could have a base requirements file, say requirements.txt, that lists common dependencies for all platforms. Then, you could have individual requirements files that are named, say, requirements.rhel53.txt, requirements.rhel63.txt, etc. The top of each of these files could have this as the first line:

-r requirements.txt

And then additional special dependencies listing. Then, in each environment, you could set an env var, let's call it $PLATFORM, and run a command like this to install dependencies:

$ pip install -r requirements.$PLATFORM.txt

Or, you could use constraints files. Your requirements.txt would just list dependencies without versions:

Foo
Bar
Baz

And then you could have a constraints file, again for each platform, that would list specific version requirements. For example, you could have constraints.rhel53.txt that had this:

Foo==1.1.0
Bar==0.1.0
Baz==2.0.1

And again, you set an env var and then run a command like this:

$ pip install -r requirements.txt -c constraints.$PLATFORM.txt

It's a cumbersome solution, but that would be one way of dealing with it. Unfortunately, pip does not have a native solution.




回答2:


I ended up with a scripted solution similar to one I found in: Is there a way to have a conditional requirements.txt file for my Python application based on platform?

Basically, I did something like the following (partial) example, which allows me to define packages as needed in the script, and still pass in requirements.txt and constraints.txt files. I'm new to Python, so please forgive (or comment on) any less-than-optimal coding practices:

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)


来源:https://stackoverflow.com/questions/35353489/pip-requirement-txt-conditionals-or-environment-markers-based-on-env-variables

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!