How to set environment variables in virtualenv

After trying dotenv package as well as the .pth method, I discovered they didn't work for me. So, I just modified the venv/bin/activate script, and exported the variables there.

Here's the idea.

$ cat venv/bin/activate

deactivate () {
    unset FOO
    unset BAR
    ...
}

...

export FOO='xxx'
export BAR='xxx'

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.


Bit hackish, but should work.

  1. Rename python link in virtual environment bin to something like python.lnk
  2. In bin folder create file python that looks like

    #!/bin/sh
    
    export TEST='It works!'
    
    "$0.lnk" "$@"
  3. Make it executable

    chmod +x python

Then if you run a script like

#!/work/venv/bin/python
import os

print 'Virtualenv variable TEST="{}"'.format(os.environ['TEST'])

as follows:

./myscript.py

it prints out:

Virtualenv variable TEST="It works!"


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'
>>>