Activate a virtualenv with a Python script

I want to activate a virtualenv instance from a Python script.

I know it's quite easy to do, but all the examples I've seen use it to run commands within the env and then close the subprocess.

I simply want to activate the virtualenv and return to the shell, the same way that bin/activate does.

Something like this:

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

Is this possible?

Relevant:

virtualenv › Invoking an env from a script


Solution 1:

If you want to run a Python subprocess under the virtualenv, you can do that by running the script using the Python interpreter that lives inside virtualenv's /bin/ directory:

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

However, if you want to activate the virtualenv under the current Python interpreter instead of a subprocess, you can use the activate_this.py script:

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

Solution 2:

The simplest solution to run your script under virtualenv's interpreter is to replace the default shebang line with path to your virtualenv's interpreter like so at the beginning of the script:

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

Make the script executable:

chmod u+x script.py

Run the script:

./script.py

Voila!

Solution 3:

It turns out that, yes, the problem is not simple, but the solution is.

First I had to create a shell script to wrap the "source" command. That said I used the "." instead, because I've read that it's better to use it than source for Bash scripts.

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

Then from my Python script I can simply do this:

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

The whole trick lies within the --rcfile argument.

When the Python interpreter exits it leaves the current shell in the activated environment.

Win!

Solution 4:

To run another Python environment according to the official Virtualenv documentation, in the command line you can specify the full path to the executable Python binary, just that (no need to active the virtualenv before):

/path/to/virtualenv/bin/python

The same applies if you want to invoke a script from the command line with your virtualenv. You don't need to activate it before:

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

The same for a Windows environment (whether it is from the command line or from a script):

> \path\to\env\Scripts\python.exe myscript.py