1

Is there a way I can write commands to a virtual environment after it's been activated? For example lets say I have a Python or Bash script which does some, stuff i.e.

  1. Make a virtualenv
  2. Activates it.
  3. Executes the commands to the shell of the newly created virtual environment?

For example I am doing something like this:

activate_this = subprocess.call("/bin/bash --rcfile " + "/home/" + os.getlogin() + "/mission-control/venv/bin/activate", shell=True)
        process = execfile(activate_this, dict(__file__=activate_this))
        process.communicate(subprocess.call(virtualenv.create_bootstrap_script(textwrap.dedent
            ("""
                import subprocess
                subprocess.call("pip install -r " + os.environ['VIRTUAL_ENV'] + "/requirements.txt", shell=True)
            """
            ))))

I would like to install the requirements.txt file after I activate the environment however I can't get the subprocess module to communicate with the shell after the virtual environment is created. I think it might have to do with me creating a new virtual environment via execfile, which therefore is creating a new process.

Also I know shell=True is bad practice but as of right now I am not concerned with the possibility of unsanitized input.

vvvvv
  • 25,404
  • 19
  • 49
  • 81
user2808315
  • 117
  • 12
  • So a shell script is calling a python script is calling a subprocess calling a python script calling a subprocess calling a shell script? Why? – Ryne Everett Oct 28 '15 at 16:47
  • 1
    On a more helpful note, I'm guessing virtualenvwrapper's [postactivate hook](http://virtualenvwrapper.readthedocs.org/en/latest/scripts.html#postactivate) is what you're looking for. – Ryne Everett Oct 28 '15 at 16:51
  • Hm, so all I really want to do is write shell commands to my venv. The first approach is to simply activate the Make then Activate the venv. Now since subprocess is the way way to communicate a python commands to the shell, all I should have to do is something like `subprocess.call("pip install -r " + os.environ['VIRTUAL_ENV'] + "/requirements.txt", shell=True)` and this should write the my venv shell, however it doesn't. I think it's because when I call execfile the venv is a different process than that of the script which started it, it could also be that venv's path may be different. – user2808315 Oct 28 '15 at 16:53
  • The create_bootstrap_script is simply an attempt at passing commands to the virtual environment. From the documentation on `create_bootstrap_script`: While this creates an environment, it doesn’t put anything into the environment. Developers may find it useful to distribute a script that sets up a particular environment, for example a script that installs a particular web application. – user2808315 Oct 28 '15 at 16:55
  • 1
    Unless you need python for this I would stick with a pure shell solution. – Ryne Everett Oct 28 '15 at 17:03

2 Answers2

0
. "$VIRTUAL_ENV/bin/activate"
pip install -r "$VIRTUAL_ENV/requirements.txt"
Ryne Everett
  • 6,427
  • 3
  • 37
  • 49
  • So when I create a Bash script to try the following I get: `Directory '/home/user/blah/venv' is not installable. File 'setup.py' not found.` – user2808315 Oct 28 '15 at 17:16
  • Hmm. I don't think there's any way to debug that without seeing the contents of your requirements file. Do the above commands work if you type them into a shell manually? – Ryne Everett Oct 28 '15 at 17:38
  • Very True @Ryne Everett. I actually may have found a solution using Bash, I will report back soon. – user2808315 Oct 28 '15 at 17:40
0

First of all, thanks to @Ryne Everett for the help. So I solved this by just ditching the Python solution and creating a Bash file which I call from subprocess in my Python script. The subprocess call executes the Bash file which handles creating and executing within the virtualenv. I am not sure how to solve this using just Python. I am sure there is a way but this seems like a simpler solution. The Bash script is the following:

#!/bin/bash 

MISSION_CONTROL="$PWD"

if [ ! -d "$MISSION_CONTROL/venv" ]; then 
    virtualenv $MISSION_CONTROL/venv --no-site-packages
    echo "Welcome to Mission Control..."
    /bin/bash --rcfile $MISSION_CONTROL/venv/bin/activate
fi 

if [ -d "$MISSION_CONTROL/venv" ]; then 
    pip install -r $MISSION_CONTROL/requirements.txt 
fi

EDIT: This may also be useful for people who are trying to do something similiar: How to source virtualenv activate in a Bash script

Community
  • 1
  • 1
user2808315
  • 117
  • 12