Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set environment variables in virtualenv

If I have python script which activates the virtualenv like this:

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

How can I set variables for this script without modifying this script?

I want this environment variable to be active for all scripts which use this virtualenv.

This means modifying this script is not a solution, since there are twenty scripts, and I don't want to modify twenty scripts.

Writing a shell wrapper-script around the python scripts would work, but I would like to avoid this.

In the past I thought a custom sitecustomize.py can be used for start-up code. But Ubuntu (AFAIK the only distribution which does this) comes with its own sitecustomize.py file, with the effect that my sitecustomize.py does not get called. See https://bugs.launchpad.net/ubuntu/+source/python2.5/+bug/197219

Here are some ways how I want to use the virtualenv:

  • Script which gets executed via unix cron.
  • virtualenv in a systemd service. See: How to enable a virtualenv in a systemd service unit?
  • via mod_wsgi (Apache): https://modwsgi.readthedocs.io/en/develop/user-guides/virtual-environments.html#daemon-mode-single-application

(I have thought about this again. I guess it setting the variables is not the job of python or virtualenv. I need a unified way to set environment variables. And in my case I would like to do this without using a shell wrapper).

like image 402
guettli Avatar asked Sep 21 '18 18:09

guettli


People also ask

How do I set environment variables in Virtualenv?

You need the postactivate hook. If you want to keep this configuration in your project directory, simply create a symlink from your project directory to $VIRTUAL_ENV/bin/postactivate . You could even automate the creation of the symlinks each time you use mkvirtualenv.

How do I set an environment variable in Python?

To permanently modify the default environment variables, click Start and search for 'edit environment variables', or open System properties, Advanced system settings and click the Environment Variables button. In this dialog, you can add or modify User and System variables.

How do you set environment variables?

Do so by pressing the Windows and R key on your keyboard at the same time. Type sysdm. cpl into the input field and hit Enter or press Ok. In the new window that opens, click on the Advanced tab and afterwards on the Environment Variables button in the bottom right of the window.


2 Answers

while writing sitecustomize.py file and changing bin/python all are feasible solutions, I would suggest another method that does not involve directly change contents inside virutalenv, by simply install a .pth file:

./venv/lib/python2.7/site-packages/_set_envs.pth

with content:

import os; os.environ['FOO'] = 'bar'

test:

$ ./venv/bin/python -c "import os; print os.getenv('FOO')"
bar

the trick is, python will load every .pth file on startup, and if there is a line starts with import, this line will be get executed, allowing inject arbitrary code.

the advantage is, you could simply write a python package to install this .pth file with setuptools, install to the virtualenv you want to change.

like image 136
georgexsh Avatar answered Sep 20 '22 16:09

georgexsh


From what I have tried, it seems if you create a sitecustomize.py file inside the virtual environment, it will take precedence over the global sitecustomize.pyinstalled in /usr/lib/python2.7 directory. Here is what I did:

Create a sitecustomize.py in the virtual environment

$ echo "import os; os.environ['FOO'] = 'BAR'" > ~/venvs/env_test/lib/python2.7/sitecustomize.py

Verify that it is getting imported and executed when running the Python binary from the virtual environment

$ ~/venvs/env_test/bin/python
Python 2.7.15rc1 (default, Apr 15 2018, 21:51:34)
[GCC 7.3.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import sitecustomize
>>> sitecustomize.__file__
'/home/abhinav/venvs/env_test/lib/python2.7/sitecustomize.py'
>>> import os
>>> os.environ['FOO']
'BAR'
>>>

Just to verify that FOO is set even without explicitly importing sitecustomize:

$ ~/venvs/env_test/bin/python
Python 2.7.15rc1 (default, Apr 15 2018, 21:51:34)
[GCC 7.3.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> os.environ['FOO']
'BAR'
>>>
like image 25
Abhinav Upadhyay Avatar answered Sep 19 '22 16:09

Abhinav Upadhyay