pip require.txt условные обозначения или маркеры среды на основе переменных env

Есть ли способ указать условные установки в файле требований pip.txt, которые основаны на значении переменной среды?

Я смог контролировать большую часть того, что мне нужно, с помощью маркеров среды, но все маркеры, о которых я знаю, работают только с определенными значениями, которые по существу предопределены Python.

Например, я хочу иметь возможность контролировать установку пакетов для RHEL 5.3, RHEL 6.3, RHEL 6.6 и т. д. Также на основе других критериев.

Было бы идеально, если бы я мог указать в файле results.txt переменную среды, которая будет проверяться на соответствие значению, которое я установил перед запуском pip. Это кажется желательным и простым функционалом. До сих пор мне не удавалось найти исчерпывающие обсуждения маркеров среды, поэтому я надеюсь, что просто пропустил какую-то ключевую информацию :-)

Спасибо большое.


person ghoff    schedule 12.02.2016    source источник


Ответы (2)


На самом деле нет способа сделать это с переменными среды. Файлы требований 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

Или вы можете использовать файлы ограничений. Ваш 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 нет нативного решения.

person mipadi    schedule 12.02.2016
comment
Мипади спасибо за отзыв. Я боялся этого. Поскольку, насколько я понимаю, маркеры среды pip на самом деле просто эквивалентны связывающей функциональности в python (например, platform_system на самом деле platform.system() в python), я надеялся, что есть способ иметь маркер, эквивалентный чему-то вроде os.environ.get('MYVARIABLE'). Боль, которую я испытываю, заключается в том, что в моих критериях требований есть несколько измерений, поэтому использование нескольких файлов требований становится немного запутанным в обслуживании. Использование файлов ограничений — хорошая идея. Я постараюсь хотя бы уменьшить сложность таким образом. - person ghoff; 12.02.2016
comment
Использование других файлов ограничений могло бы решить мою проблему довольно гладко, за исключением того, что я не могу найти способ сделать файл ограничений полностью запрещенным для пакета. Есть ли способ? Я попытался обойти это, указав несуществующую версию (например, six <= 0.1), но затем выдал ошибки, потому что не смог найти приемлемую версию для установки. Есть ли способ сказать pip, чтобы он не выдавал ошибку или предупреждал, а не ошибался? - person ghoff; 13.02.2016
comment
Я также пытался использовать маркер среды, который оценивается как ложный (например, six; sys_platform == 'win32' в среде Linux). Но вместо того, чтобы ограничивать установку пакета, pip ограничивает (игнорирует) эту строку файла ограничений и устанавливает последнюю версию пакета (поскольку она не ограничена в файле requirements.txt). - person ghoff; 13.02.2016

В итоге я получил скриптовое решение, подобное тому, которое я нашел в: Есть ли способ иметь файл условных требований.txt для моего приложения Python на основе платформы?

По сути, я сделал что-то вроде следующего (частичного) примера, который позволяет мне определять пакеты по мере необходимости в сценарии и по-прежнему передавать файлы требования.txt и ограничения.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)
person ghoff    schedule 15.02.2016
comment
Это было чрезвычайно полезно для меня. Не знал, что пакеты можно установить с помощью pip в скрипте python. аккуратный! - person Bobs Burgers; 30.08.2020