Activer un virtualenv avec un script Python

91

Je souhaite activer une instance virtualenv à partir d'un script Python.

Je sais que c'est assez facile à faire, mais tous les exemples que j'ai vus l'utilisent pour exécuter des commandes dans l'environnement, puis fermer le sous-processus.

Je veux simplement activer le virtualenv et revenir au shell, de la même manière que bin / activate.

Quelque chose comme ça:

$me: my-script.py -d env-name
$(env-name)me:

Est-ce possible?

Pertinent:

virtualenv ›Appel d'un env à partir d'un script

h3.
la source

Réponses:

88

Si vous souhaitez exécuter un sous-processus Python sous virtualenv, vous pouvez le faire en exécutant le script à l'aide de l'interpréteur Python qui se trouve dans le répertoire / bin / de virtualenv:

import subprocess

# Path to a Python interpreter that runs any Python script
# under the virtualenv /path/to/virtualenv/
python_bin = "/path/to/virtualenv/bin/python"

# Path to the script that must run under the virtualenv
script_file = "must/run/under/virtualenv/script.py"

subprocess.Popen([python_bin, script_file])

Cependant, si vous souhaitez activer virtualenv sous l'interpréteur Python actuel au lieu d'un sous-processus, vous pouvez utiliser le activate_this.pyscript:

# Doing execfile() on this file will alter the current interpreter's
# environment so you can import libraries in the virtualenv
activate_this_file = "/path/to/virtualenv/bin/activate_this.py"

execfile(activate_this_file, dict(__file__=activate_this_file))
Mensonge Ryan
la source
1
//, Cette dernière ligne du premier bloc de code de cette réponse ne devrait-elle pas se lire comme suit subprocess.Popen([venv_python_file, script_file]):?
Nathan Basanese
//, De plus, existe-t-il un moyen d'exécuter le à script_filepartir d'un emplacement arbitraire, ou doit-il être dans le virtualenvrépertoire?
Nathan Basanese
Correction, merci d'avoir remarqué l'erreur. Quant à votre deuxième question, non script_filen'a pas besoin d'être dans le répertoire virtualenv, cela peut être n'importe où.
Lie Ryan
Comment puis-je désactiver l'environnement virtuel, si j'utilise la deuxième option?
falsePockets
@falsePockets: Problème XY , pourquoi avez-vous déjà voulu faire ça?
Lie Ryan
42

La solution la plus simple pour exécuter votre script sous l'interpréteur de virtualenv est de remplacer la ligne shebang par défaut par le chemin vers l'interpréteur de votre virtualenv comme ceci au début du script:

#!/path/to/project/venv/bin/python

Rendez le script exécutable:

chmod u+x script.py

Exécutez le script:

./script.py

Voila!

nafooesi
la source
2
+1 pour l'élégance. Remarque sur Windows, cela nécessite un environnement compatible posix qui comprend les lignes Shebang comme cygwin ou msys
qneill
1
Fonctionne pour python 3.6.3 et Windows 10!
toonarmycaptain
Je pense que j'ai peut-être mal compris la question initiale. Il souhaite activer l'environnement virtuel avec un script et revenir au shell avec l'environnement activé. Ma réponse exécute le script dans l'environnement virtuel mais le shell renvoyé ne conserve pas l'environnement. La solution moderne est virtualenvwrapper: virtualenvwrapper.readthedocs.io/en/latest/# . Il permet d'activer et de basculer entre différentes virtualenvs.
nafooesi
20

Il s'avère que, oui, le problème n'est pas simple, mais la solution l'est.

J'ai d'abord dû créer un script shell pour envelopper la commande "source". Cela dit, j'ai utilisé le "." à la place, parce que j'ai lu qu'il vaut mieux l'utiliser que la source pour les scripts Bash.

#!/bin/bash
. /path/to/env/bin/activate

Ensuite, à partir de mon script Python, je peux simplement faire ceci:

import os
os.system('/bin/bash --rcfile /path/to/myscript.sh')

Toute l'astuce réside dans l' --rcfileargument.

Lorsque l'interpréteur Python se termine, il laisse le shell actuel dans l'environnement activé.

Gagner!

h3.
la source
3
Je ne comprends vraiment pas. Pourquoi ne faites-vous pas cela? os.system('/bin/bash --rcfile path/to/env/activate') Vous savez, quand une instance de bash est lancée, elle prend .bashrc comme argument pour le --rcfile. Alors spécifiez simplement que le fichier rc est votre fichier d'activation ... Non?
Depado
@Depado Je viens d'essayer votre solution et cela activera le shell dans python. au moins quand je l'essaye dans la coquille. >>> os.system ('/ bin / bash --rcfile / var / envs / test / bin / activate') (test) tcraig @ tallis-desktop: ~ $ (test) tcraig @ tallis-desktop: ~ $ ls -l total 706288
Trenton
Peut-être mais cela fonctionne dans un script. Le seul inconvénient de cette technique est que vous n'obtenez pas tous vos alias et tout ce que vous aviez dans votre ~ / .bashrc. Mais je suis d'accord avec ça. Par exemple, la commande "ls" n'a pas de couleur. Mais tout fonctionne pour moi. Quand je veux partir, je viens de Ctrl + D
Depado
7
"Lorsque l'interpréteur python se termine, il laisse le shell actuel dans l'environnement activé" Quoi? Il génère un tout nouveau shell en tant que sous-processus et attend la fin.
Kos
Afin d'éviter de créer plus de nouveaux fichiers sur mon référentiel et de répliquer également la configuration actuelle de bash, j'ai fait ceci:cat ~/.bashrc env/bin/activate > env/bin/activate2 && /bin/bash --rcfile env/bin/activate2
WhyWhat
17

Pour exécuter un autre environnement Python selon la documentation officielle de Virtualenv , dans la ligne de commande, vous pouvez spécifier le chemin complet du binaire exécutable Python, juste cela (pas besoin d'activer le virtualenv avant):

/path/to/virtualenv/bin/python

Il en va de même si vous souhaitez appeler un script depuis la ligne de commande avec votre virtualenv. Vous n'avez pas besoin de l'activer avant:

me$ /path/to/virtualenv/bin/python myscript.py

Idem pour un environnement Windows (que ce soit depuis la ligne de commande ou depuis un script):

> \path\to\env\Scripts\python.exe myscript.py
Mariano Ruiz
la source
2
La question est: Activer un virtualenv avec un script python (PAS de Shell)
Zaheer
3
Oui, mon point est que vous pouvez simplement appeler le runtime python à partir d'un environnement virtuel sans avoir besoin de l'activer auparavant, à partir de la console ou d'un script. Je vais clarifier la réponse, merci!
Mariano Ruiz
Oh mon Dieu! Je n'y ai pas pensé. c'est la seule solution qui a fonctionné pour moi :). Maintenant, lorsque j'exécute un script python à partir de php, j'utilise: "chemin / vers / virtualenv / bin / python mypythonscript.py"
Zaheer
6

Juste une solution simple qui fonctionne pour moi. Je ne sais pas pourquoi vous avez besoin du script Bash qui fait essentiellement une étape inutile (ai-je tort?)

import os
os.system('/bin/bash  --rcfile flask/bin/activate')

Ce qui fait essentiellement ce dont vous avez besoin:

[hellsing@silence Foundation]$ python2.7 pythonvenv.py
(flask)[hellsing@silence Foundation]$

Ensuite, au lieu de désactiver l'environnement virtuel, il suffit de Ctrl+ Dou de quitter. Est-ce une solution possible ou n'est-ce pas ce que vous vouliez?

Depado
la source
2

L'environnement de processus enfant est perdu au moment où il cesse d'exister, et déplacer le contenu de l'environnement de là vers le parent est quelque peu délicat.

Vous devez probablement générer un script shell (vous pouvez en générer un dynamiquement vers / tmp) qui affichera les variables d'environnement virtualenv dans un fichier, que vous lirez ensuite dans le processus Python parent et que vous placerez dans os.environ.

Ou vous analysez simplement le script d'activation en utilisant pour la ligne dans open ("bin / activate"), extrayez manuellement les éléments et mettez-les dans os.environ. C'est délicat, mais pas impossible.

Mikko Ohtamaa
la source
2
Tu veux dire quelque chose comme ca ? bitbucket.org/ianb/virtualenv/src/1f9dfb2437f1
h3.
2

La meilleure réponse ne fonctionne que pour Python 2.x

Pour Python 3.x, utilisez ceci:

activate_this_file = "/path/to/virtualenv/bin/activate_this.py"

exec(compile(open(activate_this_file, "rb").read(), activate_this_file, 'exec'), dict(__file__=activate_this_file))

Référence: Quelle est une alternative à execfile dans Python 3?

Asaad
la source
1
qu'est-ce que activate_this.py
randy Pen
1
@randyPen, le fichier activate_this.py est automatiquement ajouté lorsque vous créez le virtualenv dans le répertoire de votre projet. (ie /project/directory/venv/bin/activate_this.py)
ThéoriquementNick
-2

Vous devez créer tous vos virtualenvs dans un dossier, tel que virt.

En supposant que le nom de votre dossier virtualenv est virt, sinon changez-le

cd
mkdir custom

Copiez les lignes ci-dessous ...

#!/usr/bin/env bash
ENV_PATH="$HOME/virt/$1/bin/activate"
bash --rcfile $ENV_PATH -i

Créez un fichier de script shell et collez les lignes ci-dessus ...

touch custom/vhelper
nano custom/vhelper

Accordez une autorisation exécutable à votre fichier:

sudo chmod +x custom/vhelper

Exportez maintenant ce chemin de dossier personnalisé afin que vous puissiez le trouver sur la ligne de commande en cliquant sur l'onglet ...

export PATH = $ PATH: "$ HOME / personnalisé"

Vous pouvez maintenant l'utiliser de n'importe où en tapant simplement la commande ci-dessous ...

vhelper YOUR_VIRTUAL_ENV_FOLDER_NAME

Supposons que ce soit abc alors ...

vhelper abc
SR_Mehta
la source