Activar virtualenv con un script de Python

91

Quiero activar una instancia virtualenv desde un script de Python.

Sé que es bastante fácil de hacer, pero todos los ejemplos que he visto lo usan para ejecutar comandos dentro del entorno y luego cerrar el subproceso.

Simplemente quiero activar virtualenv y volver al shell, de la misma manera que lo hace bin / enable.

Algo como esto:

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

es posible?

Pertinente:

virtualenv ›Invocar un env desde un script

h3.
fuente

Respuestas:

88

Si desea ejecutar un subproceso de Python bajo virtualenv, puede hacerlo ejecutando el script usando el intérprete de Python que vive dentro del directorio / 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])

Sin embargo, si desea activar virtualenv bajo el intérprete de Python actual en lugar de un subproceso, puede usar el 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))
Mentira Ryan
fuente
1
//, ¿No debería leerse la última línea en el primer bloque de código de esta respuesta de la siguiente manera subprocess.Popen([venv_python_file, script_file]):?
Nathan Basanese
//, Además, ¿hay alguna forma de ejecutar el script_filedesde una ubicación arbitraria, o tiene que estar en el virtualenvdirectorio?
Nathan Basanese
Solucionado, gracias por notar el error. En cuanto a su segunda pregunta, script_fileno tiene que estar en el directorio virtualenv, puede estar en cualquier lugar.
Lie Ryan
¿Cómo puedo desactivar el entorno virtual si estoy usando la segunda opción?
falsePockets
@falsePockets: Problema XY , ¿por qué quieres hacer eso?
Lie Ryan
42

La solución más sencilla para ejecutar su script con el intérprete de virtualenv es reemplazar la línea shebang predeterminada con la ruta al intérprete de virtualenv como al principio del script:

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

Haga que el script sea ejecutable:

chmod u+x script.py

Ejecute el script:

./script.py

¡Voila!

nafooesi
fuente
2
+1 por elegancia. Tenga en cuenta que en Windows esto requiere un entorno compatible con posix que comprenda las líneas shebang como cygwin o
msys
1
¡Funciona para Python 3.6.3 y Windows 10!
toonarmycaptain
Creo que podría haber entendido mal la pregunta original. Quiere activar el entorno virtual con un script y volver al shell con el entorno activado. Mi respuesta ejecuta un script en el entorno virtual, pero el shell devuelto no retiene el entorno. La solución moderna es virtualenvwrapper: virtualenvwrapper.readthedocs.io/en/latest/# . Le permite a uno activar y cambiar entre diferentes virtualenvs.
nafooesi
20

Resulta que sí, el problema no es sencillo, pero la solución sí lo es.

Primero tuve que crear un script de shell para envolver el comando "fuente". Dicho esto, utilicé el "." en cambio, porque he leído que es mejor usarlo que el código fuente para scripts Bash.

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

Luego, desde mi script de Python, simplemente puedo hacer esto:

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

Todo el truco está dentro del --rcfile argumento.

Cuando el intérprete de Python sale, deja el shell actual en el entorno activado.

¡Ganar!

h3.
fuente
3
Realmente no lo entiendo. ¿Por qué no haces eso? os.system('/bin/bash --rcfile path/to/env/activate') Ya sabes, cuando se inicia una instancia de bash, toma .bashrc como argumento para --rcfile. Así que especifique que el rcfile es su archivo de activación ... ¿No?
Depado
@Depado Acabo de probar su solución y esto activará el shell dentro de Python. al menos cuando lo pruebo en el caparazón. >>> os.system ('/ bin / bash --rcfile / var / envs / test / bin / enable') (prueba) tcraig @ tallis-desktop: ~ $ (prueba) tcraig @ tallis-desktop: ~ $ ls -l total 706288
Trenton
Quizás, pero esto funciona en un guión. El único inconveniente de esta técnica es que no obtiene todos sus alias y todo lo que tenía en su ~ / .bashrc. Pero estoy bien con eso. Por ejemplo, el comando "ls" no tiene color. Pero todo me funciona. Cuando quiero irme, solo
presiono
7
"Cuando el intérprete de Python sale, deja el shell actual en el entorno activado" ¿Qué? Genera un shell totalmente nuevo como subproceso y espera hasta que finalice.
Kos
Para evitar crear más archivos nuevos en mi repositorio y también replicar la configuración actual de bash, hice esto:cat ~/.bashrc env/bin/activate > env/bin/activate2 && /bin/bash --rcfile env/bin/activate2
WhyWhat
17

Para ejecutar otro entorno Python de acuerdo con la documentación oficial de Virtualenv , en la línea de comando puede especificar la ruta completa al binario ejecutable de Python, solo eso (no es necesario activar virtualenv antes):

/path/to/virtualenv/bin/python

Lo mismo se aplica si desea invocar un script desde la línea de comando con su virtualenv. No es necesario activarlo antes:

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

Lo mismo para un entorno de Windows (ya sea desde la línea de comandos o desde un script):

> \path\to\env\Scripts\python.exe myscript.py
Mariano Ruiz
fuente
2
La pregunta es: active un virtualenv con un script de Python (NO desde Shell)
Zaheer
3
Sí, mi punto es que puedes simplemente llamar al tiempo de ejecución de Python desde un entorno virtual sin la necesidad de activarlo antes, desde la consola o desde un script. Aclararé la respuesta, ¡gracias!
Mariano Ruiz
¡Oh Dios mío! No pensé en eso. esta es la única solución que funcionó para mí :). Ahora, cuando estoy ejecutando un script de Python desde php, estoy usando: "ruta / a / virtualenv / bin / python mypythonscript.py"
Zaheer
6

Solo una solución simple que funciona para mí. No sé por qué necesita el script Bash que básicamente hace un paso inútil (¿me equivoco?)

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

Que básicamente hace lo que necesitas:

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

Luego, en lugar de desactivar el entorno virtual, simplemente Ctrl+ Do salir. ¿Es esa una posible solución o no es eso lo que querías?

Depado
fuente
2

El entorno del proceso hijo se pierde en el momento en que deja de existir, y mover el contenido del entorno desde allí al padre es algo complicado.

Probablemente necesite generar un script de shell (puede generar uno dinámicamente en / tmp) que generará las variables de entorno virtualenv en un archivo, que luego leerá en el proceso principal de Python y colocará en os.environ.

O simplemente analice el script de activación en el uso de la línea en abierto ("bin / activar"), extraiga manualmente cosas y coloque en os.environ. Es complicado, pero no imposible.

Mikko Ohtamaa
fuente
2
¿Te refieres a algo como esto? bitbucket.org/ianb/virtualenv/src/1f9dfb2437f1/…
h3.
2

La respuesta principal solo funciona para Python 2.x

Para Python 3.x, use esto:

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))

Referencia: ¿Cuál es una alternativa a execfile en Python 3?

Asaad
fuente
1
qué es
active_this.py
1
@randyPen, el archivo active_this.py se agrega automáticamente cuando construye el virtualenv en el directorio de su proyecto. (es decir /project/directory/venv/bin/activate_this.py)
TheoreticallyNick
-2

Debe crear todos sus virtualenvcorreos electrónicos en una carpeta, comovirt .

Suponiendo que el nombre de su carpeta virtualenv es virt, si no, cámbielo

cd
mkdir custom

Copie las siguientes líneas ...

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

Cree un archivo de script de shell y pegue las líneas anteriores ...

touch custom/vhelper
nano custom/vhelper

Otorgue permiso ejecutable a su archivo:

sudo chmod +x custom/vhelper

Ahora exporte esa ruta de carpeta personalizada para que pueda encontrarla en la línea de comandos haciendo clic en la pestaña ...

export PATH = $ PATH: "$ HOME / custom"

Ahora puede usarlo desde cualquier lugar simplemente escribiendo el siguiente comando ...

vhelper YOUR_VIRTUAL_ENV_FOLDER_NAME

Supongamos que es abc entonces ...

vhelper abc
SR_Mehta
fuente