Skip to content Skip to sidebar Skip to footer

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 th

Solution 1:

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.

Solution 2:

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

Solution 3:

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.

Solution 4:

I think the best answer here is to create a simple script and install it inside your virtualenv. Then you can either directly use the script, or create a symlink, or whatever.

Here's an example:

$ mkdir my-tool$ cd my-tool$ mkdir scripts$ touch setup.py$ mkdir scripts$ touch scripts/crunchy-frog$ chmod +x scripts/crunchy-frog

crunchy-frog

#!/usr/bin/env pythonprint("Constable Parrot ate one of those!")

setup.py

from setuptools import setup

setup(name="my-cool-tool",
      scripts=['scripts/crunchy-frog'],
      )

Now:

$ source /path/to/my/env/bin/activate
(env) $ python setup.py develop 
(env) $ deactivate
$ cd ~$ ln -s /path/to/my/env/bin/crunchy-frog crunchy-frog$ ./crunchy-frog
Constable Parrot ate one of those!

When you install your script (via setup.py install or setup.py develop) then it will replace the first line of the scripts with a shebang line for the env python (which you can verify with $ head /path/to/my/env/bin/crunchy-frog). So whenever you run that particular script, it will use that specific Python env.

Solution 5:

Does this help?

import site
site.addsitedir('/path/to/virtualenv/lib/python2.7/site-packages/')

Post a Comment for "Automatically Load A Virtualenv When Running A Script"