Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Automatically load a virtualenv when running a script

I have a python script that needs dependencies from a virtualenv. I was wondering if there was some way I could add it to my path and have it auto start it's virtualenv, run and then go back to the system's python.

I've try playing around with autoenv and .env but that doesn't seem to do exactly what I'm looking for. I also thought about changing the shabang to point to the virtualenv path but that seems fragile.

like image 766
jpiasetz Avatar asked May 15 '14 13:05

jpiasetz


People also ask

How do I turn on automatic VENV?

virtualenv-auto-activate.sh venv folder at the top level, next to your version control directory. # For example: # . # The virtualenv will be activated automatically when you enter the directory.

How do you run a virtual environment in a Python script?

To use the virtual environment you created to run Python scripts, simply invoke Python from the command line in the context where you activated it. For instance, to run a script, just run python myscript.py .

How do I enable virtualenv in bash script?

venv/bin/activate manually it activates your virtual env as it can be seen in the terminal that . venv has been activated. But when you use the same command inside the bash script it does not activate . venv , seems that the command does not have any effect when running bash script.

What does virtualenv activate do?

virtualenv is a tool for creating isolated Python environments containing their own copy of python , pip , and their own place to keep libraries installed from PyPI. It's designed to allow you to work on multiple projects with different dependencies at the same time on the same machine.


3 Answers

There are two ways to do this:

  1. Put the name of the virtual env python into first line of the script. Like this

    #!/your/virtual/env/path/bin/python

  2. Add virtual environment directories to the sys.path. Note that you need to import sys library. Like this

    import sys

    sys.path.append('/path/to/virtual/env/lib')

If you go with the second option you might need to add multiple paths to the sys.path (site etc). The best way to get it is to run your virtual env python interpreter and fish out the sys.path value. Like this:

/your/virtual/env/bin/python

Python blah blah blah

> import sys
> print sys.path
[ 'blah', 'blah' , 'blah' ]

Copy the value of sys.path into the snippet above.

like image 103
Vlad Avatar answered Oct 20 '22 04:10

Vlad


I'm surprised that nobody has mentioned this yet, but this is why there is a file called activate_this.py in the virtualenv's bin directory. You can pass that to execfile() to alter the module search path for the currently running interpreter.

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

You can put this file at the top of your script to force the script to always run in that virtualenv. Unlike the modifying hashbang, you can use relative path with by doing:

script_directory = os.path.dirname(os.path.abspath(__file__))
activate_this_file = os.path.join(script_directory, '../../relative/path/to/env/bin/activate_this.py')
like image 32
Lie Ryan Avatar answered Oct 20 '22 04:10

Lie Ryan


From the virtualenv documentation:

If you directly run a script or the python interpreter from the virtualenv’s bin/ directory (e.g. path/to/env/bin/pip or /path/to/env/bin/python script.py) there’s no need for activation.

So if you just call the python executable in your virtualenv, your virtualenv will be 'active'. So you can create a script like this:

#!/bin/bash

PATH_TO_MY_VENV=/opt/django/ev_scraper/venv/bin

$PATH_TO_MY_VENV/python -c 'import sys; print(sys.version_info)'
python -c 'import sys; print(sys.version_info)'

When I run this script on my system, the two calls to python print what you see below. (Python 3.2.3 is in my virtualenv, and 2.7.3 is my system Python.)

sys.version_info(major=3, minor=2, micro=3, releaselevel='final', serial=0)
sys.version_info(major=2, minor=7, micro=3, releaselevel='final', serial=0)

So any libraries you have installed in your virtualenv will be available when you call $PATH_TO_MY_VENV/python. Calls to your regular system python will of course be unaware of whatever is in the virtualenv.

like image 35
alan Avatar answered Oct 20 '22 06:10

alan