2016-02-12 1 views
1

Existe-t-il un moyen de spécifier des installations conditionnelles dans un fichier pip requirements.txt basé sur la valeur d'une variable d'environnement?pip require.txt conditionnels ou marqueurs d'environnement basés sur des variables d'environnement

J'ai été capable de contrôler la plupart de ce dont j'ai besoin avec des marqueurs d'environnement, mais tous les marqueurs que je connais ne fonctionnent qu'avec des valeurs spécifiques qui sont essentiellement prédéfinies par python. Par exemple, je veux être en mesure de contrôler l'installation du paquet pour RHEL 5.3 par rapport à RHEL 6.3 par rapport à RHEL 6.6, etc. Également basé sur d'autres critères.

Ce serait parfait si je pouvais spécifier dans le fichier results.txt une variable d'environnement qui serait vérifiée par rapport à une valeur que j'avais définie avant l'exécution de pip. Cela semble être une fonctionnalité souhaitable et simple. Je n'ai pas eu beaucoup de chance jusqu'ici pour trouver des discussions complètes sur les marqueurs d'environnement, donc j'espère avoir manqué un peu d'information clé :-)

Merci beaucoup.

Répondre

2

Il n'y a pas vraiment moyen de le faire avec des variables d'environnement. Les fichiers de configuration de Pip sont simplement une liste d'arguments pip install répertoriés dans un fichier. Donc, si votre fichier exigences ressemble à ceci:

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

Logiquement, pip fait ceci:

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

Malheureusement, dans ce contexte, il n'y a aucun moyen d'appliquer des variables d'environnement.

Il existe plusieurs solutions à ce problème. Un, vous pourriez avoir un fichier de conditions de base, disons requirements.txt, qui liste les dépendances communes pour toutes les plates-formes. Ensuite, vous pourriez avoir des fichiers de besoins individuels qui sont nommés, disons, requirements.rhel53.txt, requirements.rhel63.txt, etc. Le sommet de chacun de ces fichiers pourrait avoir ce que la première ligne:

-r requirements.txt 

Et puis liste supplémentaire de dépendances spéciales. Ensuite, dans chaque environnement, vous pouvez définir un var env, nous allons l'appeler $PLATFORM et exécuter une commande comme ceci pour installer les dépendances:

$ pip install -r requirements.$PLATFORM.txt 

Ou, vous pouvez utiliser constraints files. Votre requirements.txt se contentait de dépendances liste sans versions:

Foo 
Bar 
Baz 

Et alors vous pourriez avoir un fichier de contraintes, encore une fois pour chaque plate-forme, qui dresserait une liste des exigences de version spécifique. Par exemple, vous pourriez avoir constraints.rhel53.txt qui avait ceci:

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

Et encore une fois, vous définissez un var env, puis exécutez une commande comme ceci:

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

Il est une solution lourde, mais ce serait une façon de faire avec. Malheureusement, pip n'a pas de solution native.

+0

Merci pour les commentaires mipadi. J'avais peur de ça. Puisque, si je comprends bien, les marqueurs d'environnement pip sont juste des équivalents pour associer des fonctionnalités en python (comme 'platform_system' est vraiment' platform.system() 'en python,) j'espérais qu'il y avait un moyen d'avoir un marqueur équivalent à quelque chose comme 'os.environ.get ('MYVARIABLE')'. La difficulté que j'ai est qu'il y a plusieurs dimensions à mes critères d'exigence, donc l'utilisation de plusieurs fichiers d'exigences devient un peu salissante à maintenir. L'utilisation des fichiers de contraintes est une bonne idée. Je vais essayer de réduire au minimum la complexité de cette façon. – ghoff

+0

L'utilisation de différents fichiers de contraintes pourrait contourner mon problème assez facilement ** sauf ** que je ne peux pas trouver un moyen de rendre un fichier de contraintes complètement interdire un paquet. Y a-t-il un moyen? J'ai essayé de contourner ce problème en spécifiant une version inexistante (par exemple 'six <= 0.1') mais ensuite en pipant les erreurs car il ne trouve pas de version acceptable à installer. Y a-t-il un moyen de dire à pip de ne pas faire d'erreur, ou d'avertir plutôt que d'erreur? – ghoff

+0

J'ai également essayé d'utiliser un marqueur d'environnement qui a la valeur false (par exemple 'six; sys_platform == 'win32'' dans un environnement Linux). Mais au lieu de contraindre l'installation du paquet, pip contraint (ignore) cette ligne du fichier de contraintes et installe la dernière version du paquet (car elle n'est pas contrainte dans le fichier requirements.txt). – ghoff

0

J'ai fini avec une solution scriptée semblable à celui que je trouve dans: Is there a way to have a conditional requirements.txt file for my Python application based on platform?

En fait, je l'ai fait quelque chose comme ce qui suit (partielle) par exemple, ce qui me permet de définir des paquets au besoin dans le script, et passe toujours dans les fichiers requirements.txt et constraints.txt. Je suis nouveau à Python, donc s'il vous plaît pardonner (ou commenter) toutes les pratiques de codage moins-que-optimales:

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)