6

I need a python script that will activate a virtualenv, run another python program inside the virtualenv, and then close the virutalenv after the second python program closes. Here is my code:

import os
import subprocess
from subprocess import Popen

activate_dir = "C:/Users/JohnDoe/theprogram/Scripts/"
os.chdir(activate_dir)
subprocess.Popen(["activate.bat"])

cal_dir = "C:/Users/JohnDoe/theprogram/"
os.chdir(cal_dir)
os.system('python program_file.py')

However, when this code run, I get an import error from the program_file which means the virtualenv is not activated. How can I fix this?

Thanks

Edit: This is on a Windows environment.

2
  • Possible duplicate of this question maybe? stackoverflow.com/questions/6943208/… Commented Sep 5, 2017 at 14:08
  • From my understanding, the question linked is about using a python script to exclusively activate a virtualenv. My questions adds to that by changing a directory and running another python file while the virtualenv is activated. Commented Sep 5, 2017 at 14:11

2 Answers 2

7

The issue is that you are creating a new process with subprocess.Popen(["activate.bat"]) that is using that virtual environment, you're not changing your environment. What you need to do is to either call the python script in the same process you span:

os.system("source activate;python -V")

Or you could write a shell script that starts the virtual environment and calls any python script you send to it. In bash (on linux) this would be:

#!/bin/bash
# start a virtual environment and call a python module
# usage: ./runVirenvPythonModule module.py
source activate
python $1 # this is the first cmd line argument passed in
Sign up to request clarification or add additional context in comments.

2 Comments

Ah, nice answer! If I use the os.system command, how would I go from the Scripts dir where I call activate to the program dir where I call the python script?
Please note the M$ Windows-style path in OP's code. And the fact that the activation is done via a batch file. Using bash syntax in windows will be interesting.
4

I've found a method to detect, activate, and create (if needed) a virtual environment inside a Python script and run inside that virtual environment while remaining inside that script and without the use of shell commands issued from that script (except to display installed packages via pip list). Without the use of shell commands, the script becomes OS agnostic.

Here is some example code. You simply run it from whatever OS shell you are using (Windows, Linux, MacOS):

import os
import sys
import venv

def isvirtualenv():
    return sys.prefix != sys.base_prefix

def findfile(startdir, pattern):
    for root, dirs, files in os.walk(startdir):
        for name in files:
            if name.find(pattern) >= 0:
                return root + os.sep + name

    return None

venv_path = 'venv'            # This is an example path

if isvirtualenv():
    print('Already in virtual environment.')
else:
    if findfile(os.getcwd(), 'activate') is None:
        print('No virtual environment found. Creating one.')
        env = venv.EnvBuilder(with_pip = True)
        env.create(venv_path)
    else:
        print('Not in virtual environment. Virtual environment directory found.')

    # This is the heart of this script that puts you inside the virtual environment. 
    # There is no need to undo this. When this script ends, your original path will 
    # be restored.
    os.environ['PATH'] = os.path.dirname(findfile(os.getcwd(), 'activate')) + os.pathsep + os.environ['PATH']
    sys.path.insert(1, os.path.dirname(findfile(venv_path, 'easy_install.py')))

# Run your script inside the virtual environment from here
print(os.environ['PATH'])
os.system('pip list')

1 Comment

At least on my system (Windows 10) and in my virtual environments, the last line will point not to site-packages within the virtual environment (I think that's the intention) but to site-packages/setuptools/command. Maybe a better alternative would be findfile for setuptools directory, directly?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.