définition d'une variable d'environnement dans virtualenv

160

J'ai un projet Heroku qui utilise des variables d'environnement pour obtenir sa configuration, mais j'utilise d'abord virtualenv pour tester mon application localement.

Existe-t-il un moyen de définir les variables d'environnement définies sur la machine distante dans virtualenv?

Mahmoud Hanafy
la source

Réponses:

106

Mettre à jour

Depuis le 17 mai 2017, le fichier README d'autoenv indique que direnv est probablement la meilleure option et implique qu'autoenv n'est plus maintenu.

Ancienne réponse

J'ai écrit autoenv pour faire exactement ceci:

https://github.com/kennethreitz/autoenv

Kenneth Reitz
la source
12
Très drôle gif: D
chachan
3
Juste pour info, il semble que les .envfichiers bork construits par Heroku, du moins d'après mon expérience. Alors ne l'incluez pas dans votre repo. Utilisateur de longue date / grand fan d'autoenv btw. Salut Kenneth, toi un homme!
galarant
Cette réponse est-elle toujours pertinente après modification? Quelle est votre opinion sur la solution suggérée par Nagasaki45 & TheLetterN
gelé
288

Si vous utilisez virtualenvwrapper (je vous recommande vivement de le faire), vous pouvez définir différents hooks (préactiver, postactiver, prédéactiver, postdésactiver) en utilisant les scripts avec les mêmes noms dans $VIRTUAL_ENV/bin/. Vous avez besoin du crochet de post-activation.

$ workon myvenv

$ cat $VIRTUAL_ENV/bin/postactivate
#!/bin/bash
# This hook is run after this virtualenv is activated.
export DJANGO_DEBUG=True
export S3_KEY=mykey
export S3_SECRET=mysecret

$ echo $DJANGO_DEBUG
True

Si vous souhaitez conserver cette configuration dans votre répertoire de projet, créez simplement un lien symbolique à partir de votre répertoire de projet vers $VIRTUAL_ENV/bin/postactivate.

$ rm $VIRTUAL_ENV/bin/postactivate
$ ln -s .env/postactivate $VIRTUAL_ENV/bin/postactivate

Vous pouvez même automatiser la création des liens symboliques chaque fois que vous utilisez mkvirtualenv .

Nettoyage lors de la désactivation

N'oubliez pas que cela ne nettoiera pas après lui-même. Lorsque vous désactivez virtualenv, la variable d'environnement persiste. Pour nettoyer symétriquement, vous pouvez ajouter à $VIRTUAL_ENV/bin/predeactivate.

$ cat $VIRTUAL_ENV/bin/predeactivate
#!/bin/bash
# This hook is run before this virtualenv is deactivated.
unset DJANGO_DEBUG

$ deactivate

$ echo $DJANGO_DEBUG

N'oubliez pas que si vous l'utilisez pour des variables d'environnement qui peuvent déjà être définies dans votre environnement, la désactivation entraînera leur désactivation complète lorsque vous quittez virtualenv. Donc, si cela est probable, vous pouvez enregistrer la valeur précédente quelque part temporairement, puis la relire lors de la désactivation.

Installer:

$ cat $VIRTUAL_ENV/bin/postactivate
#!/bin/bash
# This hook is run after this virtualenv is activated.
if [[ -n $SOME_VAR ]]
then
    export SOME_VAR_BACKUP=$SOME_VAR
fi
export SOME_VAR=apple

$ cat $VIRTUAL_ENV/bin/predeactivate
#!/bin/bash
# This hook is run before this virtualenv is deactivated.
if [[ -n $SOME_VAR_BACKUP ]]
then
    export SOME_VAR=$SOME_VAR_BACKUP
    unset SOME_VAR_BACKUP
else
    unset SOME_VAR
fi

Tester:

$ echo $SOME_VAR
banana

$ workon myenv

$ echo $SOME_VAR
apple

$ deactivate

$ echo $SOME_VAR
banana
Danilo Bargen
la source
Juste une précision: faire ln -s .env/postactivate $VIRTUAL_ENV/bin/postactivaten'a pas fonctionné pour moi. lnveut un chemin complet, alors je devais le faireln -s `pwd`/.env/postactivate $VIRTUAL_ENV/bin/postactivate
Zoneur
@Zoneur Sur quel OS êtes-vous? Sous Linux, les chemins relatifs fonctionnent pour ln.
Danilo Bargen
@DaniloBargen J'utilise LinuxMint 3.2.0. Cette réponse dit que lnj'aime les chemins complets, alors j'ai essayé et cela a fonctionné. Quand j'ai essayé catle lien symbolique avec le chemin relatif, il a dit No such file or directory.
Zoneur
@dpwrussel, qui n'a presque pas réussi à passer en revue, c'est un bon ajout, mais c'est tellement important qu'il aurait pu être fait comme son propre message (ce qui vous aurait valu une certaine réputation). Beaucoup de bonnes réponses sont bonnes :)
Kent Fredric
2
Et le contrôle de la source? Comment cela se traduit-il par d'autres personnes qui clonent et mettent en place un projet qui a besoin de l'environnement. var.s?
CpILL le
44

Tu pourrais essayer:

export ENVVAR=value

dans virtualenv_root / bin / activate. Fondamentalement, le script d'activation est ce qui est exécuté lorsque vous commencez à utiliser virtualenv afin que vous puissiez y mettre toute votre personnalisation.

kgr
la source
2
Je ne sais pas si c'est assez propre mais ça marche définitivement!
chachan
2
Ouais, c'est bon marché et méchant, mais parfois c'est ce dont vous avez besoin.
Michael Scheper
1
Je ne le recommande pas, je l'ai fait et quelque temps plus tard, tous les scripts d'activation (activate, activate.csh, activate.fish) ont été écrasés automatiquement, j'ai donc perdu ma modification. Utilisez postactiver et prédésactiver.
wil93
ne pas utiliser d'espaces autour du =
Rik Schoonbeek
Pourrait également ajouter `` unset ENVVAR '' dans la deactivatefonction définie virtualenv_root / bin / activate pour équilibrer le réglage et la désactivation
Lou Zell
42

En utilisant uniquement virtualenv (sans virtualenvwrapper ), la configuration des variables d'environnement est facile grâce au activatescript que vous sourcez afin d'activer virtualenv.

Courir:

nano YOUR_ENV/bin/activate

Ajoutez les variables d'environnement à la fin du fichier comme ceci:

export KEY=VALUE

Vous pouvez également définir un hook similaire pour annuler la variable d'environnement comme suggéré par Danilo Bargen dans sa grande réponse ci-dessus si vous en avez besoin.

Nagasaki45
la source
9
une approche beaucoup plus sensée de l'OMI. remplacer cdjuste pour avoir des variables d'environnement? frisson
Michel Müller
que diriez-vous du nettoyage après la désactivation?
buncis le
36

Bien qu'il y ait beaucoup de bonnes réponses ici, je n'ai pas vu de solution publiée qui inclut à la fois la désactivation des variables d'environnement lors de la désactivation et ne nécessite pas de bibliothèques supplémentaires au virtualenv- delà , voici donc ma solution qui consiste simplement à modifier / bin / activate, en utilisant le variables MY_SERVER_NAMEet MY_DATABASE_URLcomme exemples:

Il devrait y avoir une définition de la désactivation dans le script d'activation, et vous souhaitez annuler la définition de vos variables à la fin:

deactivate () {
    ...

    # Unset My Server's variables
    unset MY_SERVER_NAME
    unset MY_DATABASE_URL
}

Puis à la fin du script d'activation, définissez les variables:

# Set My Server's variables
export MY_SERVER_NAME="<domain for My Server>"
export MY_DATABASE_URL="<url for database>"

De cette façon, vous n'avez rien d'autre à installer pour le faire fonctionner, et vous ne vous retrouvez pas avec les variables restantes lorsque vous deactivateutilisez virtualenv.

TheLetterN
la source
3
J'aime cette approche parce que je ne veux pas de bibliothèques ou d'applications externes, mais le problème avec cela est que si vous reconstruisez l'environnement, vous perdrez tous vos paramètres.
VStoykov
2
L'avantage de cette approche est la rapidité d'installation et le manque de magie. Garder les variables environ hors du contrôle de code source vous ramènera toujours au problème de la destruction potentielle de vos secrets / paramètres lors de la reconstruction d'environnements.
Anthony Manning-Franklin
Le répertoire virtualenv finit-il par être archivé dans le référentiel pour que cela fonctionne? Que faire si les variables contiennent des secrets que vous ne voulez pas dans le dépôt? Comment voulez-vous gérer cela?
fraxture le
2
Je ne vois pas vraiment pourquoi ce serait une bonne idée d'inclure un virtualenv dans votre référentiel, car ils ne sont pas très portables, mais j'imagine que vous pouvez mettre vos exportations dans un fichier séparé au lieu du script d'activation et générer le fichier si il est présent et n'ajoutez pas ce fichier à votre référentiel.
TheLetterN
18

Localement, dans un virtualenv, vous pouvez utiliser deux méthodes pour tester cela. Le premier est un outil qui s'installe via la ceinture à outils Heroku (https://toolbelt.heroku.com/). L'outil est contremaître. Il exportera toutes vos variables d'environnement qui sont stockées dans un fichier .env localement, puis exécutera les processus d'application dans votre Procfile.

La deuxième façon si vous recherchez une approche plus légère est d'avoir un fichier .env localement, puis exécutez:

export $(cat .env)
CraigKerstiens
la source
6

Installez autoenv soit en

$ pip install autoenv

(ou)

$ brew install autoenv

Et puis créez le .envfichier dans votre dossier de projet virtualenv

$ echo "source bin/activate" > .env

Maintenant, tout fonctionne bien.

Fizer Khan
la source
3

Si vous utilisez déjà Heroku, envisagez d'exécuter votre serveur via Foreman . Il prend en charge un .envfichier qui est simplement une liste de lignes KEY=VALqui seront exportées vers votre application avant son exécution.

Michael Mior
la source
1

Pour activer virtualenv dans le envrépertoire et exporter les variables d'environnement stockées en cours d' .envutilisation:

source env/bin/activate && set -a; source .env; set +a
Daniil Mashkin
la source
enregistrer dans les alias avececho 'alias e=". env/bin/activate && set -a; source .env; set +a"' >> ~/.bash_aliases
Daniil Mashkin