Determine if Python is running inside virtualenv
The most reliable way to check for this is to check whether sys.prefix == sys.base_prefix
. If they are equal, you are not in a virtual environment; if they are unequal, you are. Inside a virtual environment, sys.prefix
points to the virtual environment, and sys.base_prefix
is the prefix of the system Python the virtualenv was created from.
The above always works for Python 3 stdlib venv
and for recent virtualenv
(since version 20). Older versions of virtualenv
used sys.real_prefix
instead of sys.base_prefix
(and sys.real_prefix
did not exist outside a virtual environment), and in Python 3.3 and earlier sys.base_prefix
did not ever exist. So a fully robust check that handles all of these cases could look like this:
import sys
def get_base_prefix_compat():
"""Get base/real prefix, or sys.prefix if there is none."""
return getattr(sys, "base_prefix", None) or getattr(sys, "real_prefix", None) or sys.prefix
def in_virtualenv():
return get_base_prefix_compat() != sys.prefix
If you only care about supported Python versions and latest virtualenv
, you can replace get_base_prefix_compat()
with simply sys.base_prefix
.
Using the VIRTUAL_ENV
environment variable is not reliable. It is set by the virtualenv activate
shell script, but a virtualenv can be used without activation by directly running an executable from the virtualenv's bin/
(or Scripts
) directory, in which case $VIRTUAL_ENV
will not be set. Or a non-virtualenv Python binary can be executed directly while a virtualenv is activated in the shell, in which case $VIRTUAL_ENV
may be set in a Python process that is not actually running in that virtualenv.
how can I find out which python virtual environment I am using?
You can use sys.prefix
to determine which virtualenv you're in.
import sys
print(sys.prefix)
from the sys
docs
A string giving the site-specific directory prefix where the platform independent Python files are installed
How to test if Python is running from a virtualenv during package installation
Ultimately it seems that your question is really about how to detect whether the running Python is in a virtualenv. To get to the bottom of this we must understand how virtualenv
actually works.
When you run the activate
script inside a virtualenv, it does two things:
- it updates the
PATH
environment variable to include thebin
directory from the virtualenv, so that when you runpython
the binary from the virtualenv will run. - it sets a variable
VIRTUAL_ENV
so that the activate script itself can keep track of the activation.
It's perfectly acceptable to directly run the python
from the virtualenv, and at runtime python
does not use the VIRTUAL_ENV
variable at all. Instead, it determines the directory containing the running python
binary and uses the parent directory as its "prefix".
You can determine the system's prefix by importing the sys
module and consulting sys.prefix
. However, it would be a bad idea to depend on the value of this when a virtualenv is not activated because this is a build-time setting for Python that can easily be customized, and it will definitely vary between platforms.
However, Python does have one slight runtime difference when it runs from a virtualenv prefix vs. its compiled-in prefix: the sys
package has an additional variable real_prefix
that returns the prefix that is compiled into the Python binary. Therefore one could use this to recognize that Python is running in a non-default location, which is reasonably likely to mean it's running from a virtualenv:
import sys
if getattr(sys, "real_prefix", None) is not None:
print "Maybe in a virtualenv"
else:
print "Probably not in a virtualenv"
However, even this is not an exact science. All this really tells you is that the python binary is not at the location specified at compile time. It does not tell you whether the current user has access to write to /usr/share/man
-- there are some (possibly edge) cases where this won't give you the right answer:
If the user has compiled his own Python from source in his home directory and its compiled prefix is
/home/johnd/local-python
thenreal_prefix
won't be set but the user still has write access to his Pythonlib
directory, and probably not write access to/etc
or/usr/share/man
Likewise, on some systems the administrator may have granted group-write privileges on
/usr/lib/python2.7
to a certain group of app developers so that they can install Python modules, but not have granted them write access to other system files.
So I think in the end the best you can do is a heuristic and it may be better to instead just avoid using absolute paths in data_files
for any module you expect to be used inside a virtualenv. A compromise might be to simply split your module into two distributions, one representing the localizable source files and another representing the system-wide configuration to make it run. The latter can depend on the former so that users can still easily install it, but those using virtualenv
have the option of using the other former directly.
How can a shell function know if it is running within a virtualenv?
Actually, I just found a similar question, from which one can easily derive an answer to this one:
Python: Determine if running inside virtualenv
E.g., a shell script can use something like
python -c 'import sys; print (sys.real_prefix)' 2>/dev/null && INVENV=1 || INVENV=0
(Thanks to Christian Long for showing how to make this solution work with Python 3 also.)
EDIT: Here's a more direct (hence clearer and cleaner) solution (taking a cue from JuanPablo's comment):
INVENV=$(python -c 'import sys; print ("1" if hasattr(sys, "real_prefix") else "0")')
Python: How do you check what is in virtualenv?
Once you activate your virtual environment, you should be able to list out packages using pip list
and verify version using python --version
.
Python script inside virtual env not running in command line
If you want to directly run a script in a virtual env, edit the shebang line to include the Python interpreter from that env:
#!/path/to/env/bin/python3
That interpreter will find the pyvenv.cfg
file at its parent directory and will adjust all paths accordingly. That is an equivalent of activating the environmnet.
The process can be automated. Create a package with a setup.py
and declare which files are scripts. When the package is installed, the scripts will installed in the <venv>/bin
subdirectory with correct shebang lines.
You may want to create a symlink from /usr/bin
to have the script in the path.
Activate virtualenv from a system running a different python version
A virtualenv doesn't have a full Python installation. Instead, it links to an installation present on the system (FYI that link is in <env>/lib/orig-prefix.txt
). The env's directory tree has some stubs and special logic but it uses the bulk from that installation.
So if you run activate
on a system that doesn't have the same Python at the same path as the one virtualenv was created for, that script won't work correctly. It might happen to hook to something else present at the same path but this is not a supported scenario so all bets are off.
If you need a "fully enclosed environment", you may want to take a look at pyenv
which does exactly that -- installs a full Python under your home dir. (Or you can just install Python from source to somewhere under your home dir -- but pyenv
makes it easy to switch to that installation and back.)
Related Topics
Cannot Concatenate 'Str' and 'Float' Objects
Running Python on Windows for Node.Js Dependencies
Python Pandas Counting the Occurrences of a Specific Value
Python: How to Make the Ansi Escape Codes to Work Also in Windows
How to Create a View Onto a Numpy Array
How to Dynamically Create Derived Classes from a Base Class
How to Convert a String Date into Datetime Format in Python
Does Python Have a Bitfield Type
Sorting a List of Dot-Separated Numbers, Like Software Versions
How to Profile Python Code Line-By-Line
How to Clamp an Integer to Some Range
Adding a Background Image to a Plot
How to Login to a Website with Python
How to Send Cookies in a Post Request with the Python Requests Library