¿Es posible determinar si el script actual se está ejecutando dentro de un entorno virtualenv?
¿Es posible determinar si el script actual se está ejecutando dentro de un entorno virtualenv?
Respuestas:
AFAIK la forma más confiable de verificar esto (y la forma en que se usa internamente en virtualenv y en pip) es verificar la existencia de sys.real_prefix:
import sys
if hasattr(sys, 'real_prefix'):
#...
Dentro de un virtualenv, sys.prefixapunta al directorio virtualenv, y sys.real_prefixapunta al prefijo "real" del sistema de Python (a menudo /usro /usr/localo algo así).
Fuera de un virtualenv, sys.real_prefixno debería existir.
Usar la VIRTUAL_ENVvariable de entorno no es confiable. Está configurado por el activatescript de shell virtualenv , pero un virtualenv puede usarse sin activación ejecutando directamente un ejecutable desde el directorio virtualenv bin/(o Scripts), en cuyo caso $VIRTUAL_ENVno se establecerá.
PYTHON_ENV=$(python -c "import sys; sys.stdout.write('1') if hasattr(sys, 'real_prefix') else sys.stdout.write('0')")
Intenta usar pip -V(nota mayúscula V)
Si está ejecutando el entorno virtual. mostrará el camino a la ubicación del entorno.
virtualenvmucho, es posible que esto pueda fallar o mentirte. Si está mintiendo, puedes hacerlo find /path/to/venv/ -type f -exec sed -ie "s:/old/path/to/venv:/path/to/venv:g" {} \+. Si está fallando (obtuve "datos incorrectos del mariscal"), deberá borrar los archivos .pyc find /path/to/venv -type f -name "*.pyc" -exec rm {} \+(no se preocupe, se reconstruirán automáticamente).
...\lib\site-packagesen %PATH%. Entonces devolverá un falso positivo en ese caso.
Esta es una mejora de la respuesta aceptada por Carl Meyer . Funciona con virtualenv para Python 3 y 2 y también para el módulo venv en Python 3:
import sys
def is_venv():
return (hasattr(sys, 'real_prefix') or
(hasattr(sys, 'base_prefix') and sys.base_prefix != sys.prefix))
El cheque para sys.real_prefixcubiertas virtualenv, la igualdad de no vacías sys.base_prefixcon sys.prefixcubiertas venv.
Considere un script que usa la función de esta manera:
if is_venv():
print('inside virtualenv or venv')
else:
print('outside virtualenv or venv')
Y la siguiente invocación:
$ python2 test.py
outside virtualenv or venv
$ python3 test.py
outside virtualenv or venv
$ python2 -m virtualenv virtualenv2
...
$ . virtualenv2/bin/activate
(virtualenv2) $ python test.py
inside virtualenv or venv
(virtualenv2) $ deactivate
$ python3 -m virtualenv virtualenv3
...
$ . virtualenv3/bin/activate
(virtualenv3) $ python test.py
inside virtualenv or venv
(virtualenv3) $ deactivate
$ python3 -m venv venv3
$ . venv3/bin/activate
(venv3) $ python test.py
inside virtualenv or venv
(venv3) $ deactivate
def is_venv(): return hasattr(sys, 'real_prefix') or sys.base_prefix != sys.prefix. Sólo digo'.
pipenventornos virtuales creados.
Verifique la $VIRTUAL_ENVvariable de entorno.
La $VIRTUAL_ENVvariable de entorno contiene el directorio del entorno virtual cuando se encuentra en un entorno virtual activo.
>>> import os
>>> os.environ['VIRTUAL_ENV']
'/some/path/project/venv'
Una vez que ejecuta deactivate/ abandona el entorno virtual, la $VIRTUAL_ENVvariable se borrará / vaciará. Python generará un KeyErrorporque la variable de entorno no estaba configurada.
>>> import os
>>> os.environ['VIRTUAL_ENV']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/Cellar/python/3.7.3/Frameworks/Python.framework/Versions/3.7/lib/python3.7/os.py", line 678, in __getitem__
raise KeyError(key) from None
KeyError: 'VIRTUAL_ENV'
Estas mismas comprobaciones de variables de entorno, por supuesto, también se pueden hacer fuera del script de Python, en el shell.
virtualenvvirtualenv como para un venvvirtualenv.
De acuerdo con virtualenv pep en http://www.python.org/dev/peps/pep-0405/#specification , puede usar sys.prefix en lugar de os.environ ['VIRTUAL_ENV'].
sys.real_prefix no existe en mi virtualenv y lo mismo ocurre con sys.base_prefix.
sys.real_prefix.
env |grep VIRTUAL_ENV |wc -l que devolverá un 1 si está en un venv o un 0 si no.
[[ -n $VIRTUAL_ENV ]] && echo virtualenvo [[ -z $VIRTUAL_ENV ]] && echo not virtualenvsegún sus necesidades.
Para verificar si está dentro de Virtualenv:
import os
if os.getenv('VIRTUAL_ENV'):
print('Using Virtualenv')
else:
print('Not using Virtualenv')
También puede obtener más datos sobre su entorno:
import sys
import os
print(f'Python Executable: {sys.executable}')
print(f'Python Version: {sys.version}')
print(f'Virtualenv: {os.getenv("VIRTUAL_ENV")}')
Aquí hay varias buenas respuestas, y algunas menos robustas. Aquí hay una descripción general.
No confíe en la ubicación de Python o la site-packagescarpeta.
Si se configuran en ubicaciones no estándar, eso no significa que esté realmente en un entorno virtual. Los usuarios pueden tener más de una versión de Python instalada, y no siempre están donde espera que estén.
Evita mirar:
sys.executablesys.prefixpip -Vwhich pythonAdemás, no se verifique la presencia de venv, .venvo envsen cualquiera de estos caminos. Esto se romperá para entornos con una ubicación más única. Por ejemplo,
Pipenv usa valores hash como nombre para sus entornos.
VIRTUAL_ENV Variable ambientalAmbos virtualenvy venvestablecer la variable de entorno $VIRTUAL_ENVal activar un entorno. Ver PEP 405 .
Puede leer esta variable en scripts de shell o usar este código de Python para determinar si está configurado.
import os
running_in_virtualenv = "VIRTUAL_ENV" in os.environ
# alternative ways to write this, also supporting the case where
# the variable is set but contains an empty string to indicate
# 'not in a virtual environment':
running_in_virtualenv = bool(os.environ.get("VIRTUAL_ENV"))
running_in_virtualenv = bool(os.getenv("VIRTUAL_ENV"))
El problema es que esto sólo funciona cuando el ambiente se activa por el activatescript de shell.
Puede iniciar los scripts del entorno sin activar el entorno , por lo que si eso le preocupa, debe usar un método diferente.
sys.base_prefixvirtualenv, venvY el pyvenvpunto sys.prefixa la de Python instalado en el interior de la virtualenv como era de esperar.
Al mismo tiempo, el valor original de sys.prefixtambién está disponible como sys.base_prefix.
Podemos usar eso para detectar si estamos en un virtualenv.
import sys
# note: Python versions before 3.3 don't have sys.base_prefix
# if you're not in virtual environment
running_in_virtualenv = sys.prefix != sys.base_prefix
sys.real_prefixAhora tenga cuidado, virtualenvantes de que la versión 20 no se configurara, sys.base_prefixsino que se configuraba sys.real_prefix.
Entonces, para estar seguro, verifique ambos como se sugiere en la respuesta de hroncok :
import sys
real_prefix = getattr(sys, "real_prefix", None)
base_prefix = getattr(sys, "base_prefix", sys.prefix)
running_in_virtualenv = (base_prefix or real_prefix) != sys.prefix
Si está utilizando entornos virtuales Anaconda, verifique la respuesta de Victoria Stuart .
running_in_virtualenv = sys.*base_*prefix != sys.prefix
if hasattr(sys, 'real_prefix'):prueba, que ya no funcionaba.
Puede hacer which pythony ver si apunta al que está en el entorno virtual.
whichno está disponible por defecto en Windows. En su wherelugar, puede usar en Windows o emplear whichcraft . O mira sys.executable. Pero aún así, hay mejores métodos.
Yo uso habitualmente varios entornos virtuales instalados por Anaconda (venv). Este fragmento de código / ejemplos le permite determinar si se encuentra o no en un venv (o en el entorno de su sistema), y también puede requerir un venv específico para su script.
Agregar al script de Python (fragmento de código):
# ----------------------------------------------------------------------------
# Want script to run in Python 3.5 (has required installed OpenCV, imutils, ... packages):
import os
# First, see if we are in a conda venv { py27: Python 2.7 | py35: Python 3.5 | tf: TensorFlow | thee : Theano }
try:
os.environ["CONDA_DEFAULT_ENV"]
except KeyError:
print("\tPlease set the py35 { p3 | Python 3.5 } environment!\n")
exit()
# If we are in a conda venv, require the p3 venv:
if os.environ['CONDA_DEFAULT_ENV'] != "py35":
print("\tPlease set the py35 { p3 | Python 3.5 } environment!\n")
exit()
# See also:
# Python: Determine if running inside virtualenv
# http://stackoverflow.com/questions/1871549/python-determine-if-running-inside-virtualenv
# [ ... SNIP! ... ]
Ejemplo:
$ p2
[Anaconda Python 2.7 venv (source activate py27)]
(py27) $ python webcam_.py
Please set the py35 { p3 | Python 3.5 } environment!
(py27) $ p3
[Anaconda Python 3.5 venv (source activate py35)]
(py35) $ python webcam.py -n50
current env: py35
processing (live): found 2 faces and 4 eyes in this frame
threaded OpenCV implementation
num_frames: 50
webcam -- approx. FPS: 18.59
Found 2 faces and 4 eyes!
(py35) $
Actualización 1 - uso en scripts bash:
También puede usar este enfoque en scripts de bash (por ejemplo, aquellos que deben ejecutarse en un entorno virtual específico). Ejemplo (agregado al script bash):
if [ $CONDA_DEFAULT_ENV ] ## << note the spaces (important in BASH)!
then
printf 'venv: operating in tf-env, proceed ...'
else
printf 'Note: must run this script in tf-env venv'
exit
fi
Actualización 2 [Nov 2019]
Desde mi publicación original, me mudé de Anaconda venv (y Python ha evolucionado en entornos virtuales viz-a-viz ).
Reexaminando este problema, aquí hay un código Python actualizado que puede insertar para probar que está operando en un entorno virtual Python específico (venv).
import os, re
try:
if re.search('py37', os.environ['VIRTUAL_ENV']):
pass
except KeyError:
print("\n\tPlease set the Python3 venv [alias: p3]!\n")
exit()
Aquí hay un código explicativo.
[victoria@victoria ~]$ date; python --version
Thu 14 Nov 2019 11:27:02 AM PST
Python 3.8.0
[victoria@victoria ~]$ python
Python 3.8.0 (default, Oct 23 2019, 18:51:26)
[GCC 9.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import os, re
>>> re.search('py37', os.environ['VIRTUAL_ENV'])
<re.Match object; span=(20, 24), match='py37'>
>>> try:
... if re.search('py37', os.environ['VIRTUAL_ENV']):
... print('\n\tOperating in Python3 venv, please proceed! :-)')
... except KeyError:
... print("\n\tPlease set the Python3 venv [alias: p3]!\n")
...
Please set the Python3 venv [alias: p3]!
>>> [Ctrl-d]
now exiting EditableBufferInteractiveConsole...
[victoria@victoria ~]$ p3
[Python 3.7 venv (source activate py37)]
(py37) [victoria@victoria ~]$ python --version
Python 3.8.0
(py37) [victoria@victoria ~]$ env | grep -i virtual
VIRTUAL_ENV=/home/victoria/venv/py37
(py37) [victoria@victoria ~]$ python
Python 3.8.0 (default, Oct 23 2019, 18:51:26)
[GCC 9.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import os, re
>>> try:
... if re.search('py37', os.environ['VIRTUAL_ENV']):
... print('\n\tOperating in Python3 venv, please proceed! :-)')
... except KeyError:
... print("\n\tPlease set the Python3 venv [alias: p3]!\n")
...
Operating in Python3 venv, please proceed! :-)
>>>
La forma más fácil es simplemente ejecutar: which pythonsi está en un virtualenv, apuntará a su pitón en lugar del global.
(editado) Encontré de esa manera, ¿qué piensas de eso? (también devuelve la ruta de base de venv y funciona incluso para readthedocs donde no se verifica la variable env ):
import os
import sys
from distutils.sysconfig import get_config_vars
def get_venv_basedir():
"""Returns the base directory of the virtualenv, useful to read configuration and plugins"""
exec_prefix = get_config_vars()['exec_prefix']
if hasattr(sys, 'real_prefix') is False or exec_prefix.startswith(sys.real_prefix):
raise EnvironmentError('You must be in a virtual environment')
return os.path.abspath(get_config_vars()['exec_prefix'] + '/../')
Ya hay muchos métodos excelentes publicados aquí, pero solo agregando uno más:
import site
site.getsitepackages()
te dice dónde están pipinstalados los paquetes.
site.getsitepackages()genera un directorio que no es el del sistema, puede deducir que se encuentra en un entorno virtual.
virtualenv.
venvestás usando.
En el sistema operativo Windows, ve algo como esto:
C:\Users\yourusername\virtualEnvName\Scripts>activate
(virtualEnvName) C:\Users\yourusername\virtualEnvName\Scripts>
Los paréntesis significan que en realidad se encuentra en el entorno virtual llamado "virtualEnvName".
Una posible solución es:
os.access(sys.executable, os.W_OK)
En mi caso, realmente solo quería detectar si podía instalar elementos con pip tal cual. Si bien puede no ser la solución correcta para todos los casos, considere simplemente verificar si tiene permisos de escritura para la ubicación del ejecutable de Python.
Nota: esto funciona en todas las versiones de Python, pero también regresa Truesi ejecuta el sistema Python con sudo. Aquí hay un caso de uso potencial:
import os, sys
can_install_pip_packages = os.access(sys.executable, os.W_OK)
if can_install_pip_packages:
import pip
pip.main(['install', 'mypackage'])
Esta es una vieja pregunta, pero muchos ejemplos anteriores son demasiado complicados.
Keep It Simple: (en el terminal Jupyter Notebook o Python 3.7.1 en Windows 10)
import sys
print(sys.executable)```
# example output: >> `C:\Anaconda3\envs\quantecon\python.exe`
OR
```sys.base_prefix```
# Example output: >> 'C:\\Anaconda3\\envs\\quantecon'
envsesa ruta, dejará de funcionar cuando se mueva de anaconda a virtualenvo pipenv.