2

I am trying to create a python script for automating some of my personal stuff. In the script, I first want to activate my virtual environment and then do some other tasks, (API calls and processing them). But in the script.py the command that is responsible for activating the virtual environment is not working. I have tried

import subprocess
subprocess.Popen(['D:/work/venv/scripts/activate'], shell=True) # Not Working
subprocess.run(['D:/work/venv/scripts/activate'], shell=True) # Not Working

But this is not activating venv, I have also tried, but this seems not to work

import os
os.system('D:/work/venv/scripts/activate') # Not Working

I have also tried

activate_this = 'D:/Work/venv/scripts/activate_this.py' # Not working
with open(activate_this) as f:
    code = compile(f.read(), activate_this, 'exec')
    exec(code, dict(__file__=activate_this))

None of the above worked In linux/ubuntu shell script does the job done

source venv/bin/activate

I want something similar but using python script, which will be able to activate the virtual environment in the shell/cmd

Khan Asfi Reza
  • 566
  • 5
  • 28
  • Does this answer your question? [Activate a virtualenv with a Python script](https://stackoverflow.com/questions/6943208/activate-a-virtualenv-with-a-python-script) – crock Jun 16 '22 at 17:49
  • @crock unfortunately I have tried those but that doesn't work – Khan Asfi Reza Jun 16 '22 at 17:58

1 Answers1

1

Looks like this answer I linked doesn't work for Python 3, but in the comments for the answer in that post I found the following from @Calimo which worked for me:

activate_this_file = "/path/to/venv/bin/activate_this.py"
exec(compile(open(activate_this_file, "rb").read(), activate_this_file, 'exec'), dict(__file__=activate_this_file))

Edit: After some discussion it looks like the real issue was using subprocess without specifying the correct environment. By default subprocess spawns a new process using the global environment. Specify the desired virtual environment by providing the env arg when calling subprocess, ex after activating the virtual environment with the code above:

venv= os.environ.copy()
subprocess.check_all(["pip3", "install", "flask"], env=venv)
crock
  • 423
  • 3
  • 11
  • Still doesn't work, even after executing this line of code, it is referring to the global python package not to the virtual env – Khan Asfi Reza Jun 16 '22 at 18:14
  • Firstly I am trying to activate the venv, then later in the script based on some yaml file I am trying to install some python packages and then run them, but the python packages are not being installed in the virtualenv but rather it is installing in the global python environment – Khan Asfi Reza Jun 16 '22 at 18:18
  • Can you update your question to include the code that is failing? @KhanAsfiReza – crock Jun 16 '22 at 18:18
  • Actually there's nothing that is failing, I am trying to make a cli type tool that can read packages/dependencies from a yaml file and then install those libraries in the virtualenv that I will work on, not anything is failing, I just want to keep them in my venv directory not global python directory Pseducode ` ACTIVATE VENV; LIBS = READ YAML; FOR LIB IN LIBS: INSTALL LIB; ` – Khan Asfi Reza Jun 16 '22 at 18:22
  • The more I read about your problem, the more I wonder if it's better suited to shell scripting. It would be a lot easier (in my mind) to build a cli tool with a simple bash script which would generate a virtualenv and install dependencies to that virtualenv. I found [this question](https://stackoverflow.com/questions/12332975/installing-python-module-within-code) which has a lot of discussion on the topic of installing dependencies in Python code. – crock Jun 16 '22 at 18:30
  • In fact, the [pip documentation](https://pip.pypa.io/en/latest/user_guide/#using-pip-from-your-program) even states that this might not be a good idea... – crock Jun 16 '22 at 18:32
  • For installing libs I am using safe way `subprocess.check_all(["pip3", "install", "flask"])` – Khan Asfi Reza Jun 16 '22 at 18:37
  • Well `subprocess` spawns a new process, you'd have to modify the process' environment using the `env` arg before installing any dependencies with it, otherwise it will just use the global environment. Ex: `subprocess.check_all(["pip3", "install", "flask"], env=venv)`. Related question: https://stackoverflow.com/questions/2231227/python-subprocess-popen-with-a-modified-environment – crock Jun 16 '22 at 18:47
  • Great, I'll update my answer :) – crock Jun 16 '22 at 18:52
  • @KhanAsfiReza I updated my answer, if you could mark it as the accepted answer that would be great! – crock Jun 16 '22 at 18:57