setting an environment variable in virtualenv

Question:

I have a Heroku project that uses environment variables to get its configuration, but I use virtualenv to test my app locally first.

Is there a way to set the environment variables defined on the remote machine inside virtualenv?

Asked By: Mahmoud Hanafy

||

Answers:

You could try:

export ENVVAR=value

in virtualenv_root/bin/activate.
Basically the activate script is what is executed when you start using the virtualenv so you can put all your customization in there.

Answered By: kgr

Locally within an virtualenv there are two methods you could use to test this. The first is a tool which is installed via the Heroku toolbelt (https://toolbelt.heroku.com/). The tool is foreman. It will export all of your environment variables that are stored in a .env file locally and then run app processes within your Procfile.

The second way if you’re looking for a lighter approach is to have a .env file locally then run:

export $(cat .env)
Answered By: CraigKerstiens

Update

As of 17th May 2017 the README of autoenv states that direnv is probably the better option and implies autoenv is no longer maintained.

Old answer

I wrote autoenv to do exactly this:

https://github.com/kennethreitz/autoenv

Answered By: Kenneth Reitz

In case you’re using virtualenvwrapper (I highly recommend doing so), you can define different hooks (preactivate, postactivate, predeactivate, postdeactivate) using the scripts with the same names in $VIRTUAL_ENV/bin/. You need the postactivate hook.

$ workon myvenv

$ cat $VIRTUAL_ENV/bin/postactivate
#!/bin/bash
# This hook is run after this virtualenv is activated.
export DJANGO_DEBUG=True
export S3_KEY=mykey
export S3_SECRET=mysecret

$ echo $DJANGO_DEBUG
True

If you want to keep this configuration in your project directory, simply create a symlink from your project directory to $VIRTUAL_ENV/bin/postactivate.

$ rm $VIRTUAL_ENV/bin/postactivate
$ ln -s .env/postactivate $VIRTUAL_ENV/bin/postactivate

You could even automate the creation of the symlinks each time you use mkvirtualenv.

Cleaning up on deactivate

Remember that this wont clean up after itself. When you deactivate the virtualenv, the environment variable will persist. To clean up symmetrically you can add to $VIRTUAL_ENV/bin/predeactivate.

$ cat $VIRTUAL_ENV/bin/predeactivate
#!/bin/bash
# This hook is run before this virtualenv is deactivated.
unset DJANGO_DEBUG

$ deactivate

$ echo $DJANGO_DEBUG

Remember that if using this for environment variables that might already be set in your environment then the unset will result in them being completely unset on leaving the virtualenv. So if that is at all probable you could record the previous value somewhere temporary then read it back in on deactivate.

Setup:

$ cat $VIRTUAL_ENV/bin/postactivate
#!/bin/bash
# This hook is run after this virtualenv is activated.
if [[ -n $SOME_VAR ]]
then
    export SOME_VAR_BACKUP=$SOME_VAR
fi
export SOME_VAR=apple

$ cat $VIRTUAL_ENV/bin/predeactivate
#!/bin/bash
# This hook is run before this virtualenv is deactivated.
if [[ -n $SOME_VAR_BACKUP ]]
then
    export SOME_VAR=$SOME_VAR_BACKUP
    unset SOME_VAR_BACKUP
else
    unset SOME_VAR
fi

Test:

$ echo $SOME_VAR
banana

$ workon myenv

$ echo $SOME_VAR
apple

$ deactivate

$ echo $SOME_VAR
banana
Answered By: Danilo Bargen

If you’re already using Heroku, consider running your server via Foreman. It supports a .env file which is simply a list of lines with KEY=VAL that will be exported to your app before it runs.

Answered By: Michael Mior

Another way to do it that’s designed for django, but should work in most settings, is to use django-dotenv.

Answered By: Ted

Using only virtualenv (without virtualenvwrapper), setting environment variables is easy through the activate script you’re sourcing in order to activate the virtualenv.

On unix, run:

nano YOUR_ENV/bin/activate

or if you’re on windows:

nano YOUR_ENV/Scripts/activate.bat

Then, add the environment variables to the end of the file. If you’re on unix:

export KEY=VALUE

or if you’re on windows:

set KEY=VALUE

You can also set a similar hook to unset the environment variable as suggested by Danilo Bargen in his excellent answer above.

Answered By: Nagasaki45

Install autoenv either by

$ pip install autoenv

(or)

$ brew install autoenv

And then create .env file in your virtualenv project folder

$ echo "source bin/activate" > .env

Now everything works fine.

Answered By: Fizer Khan

While there are a lot of nice answers here, I didn’t see a solution posted that both includes unsetting environment variables on deactivate and doesn’t require additional libraries beyond virtualenv, so here’s my solution that just involves editing /bin/activate, using the variables MY_SERVER_NAME and MY_DATABASE_URL as examples:

There should be a definition for deactivate in the activate script, and you want to unset your variables at the end of it:

deactivate () {
    ...

    # Unset My Server's variables
    unset MY_SERVER_NAME
    unset MY_DATABASE_URL
}

Then at the end of the activate script, set the variables:

# Set My Server's variables
export MY_SERVER_NAME="<domain for My Server>"
export MY_DATABASE_URL="<url for database>"

This way you don’t have to install anything else to get it working, and you don’t end up with the variables being left over when you deactivate the virtualenv.

Answered By: TheLetterN

To activate virtualenv in env directory and export envinroment variables stored in .env use :

source env/bin/activate && set -a; source .env; set +a

Or just the following line for pyenv:

set -a; source .env; set +a
Answered By: Daniil Mashkin

Concerning the standard venv package, here is a solution that:

  • sets or updates an environment variable on activation.
  • restores the previous value of the environment variable on deactivation.

SOLUTION:

  1. Create the MY_ENV environment.
python -m venv MY_ENV
  1. Open the activate script in any text editor (e.g vim).
vim MY_ENV/bin/activate
  1. Update the body of the deactivate function.

These lines are executed when you deactivate the virtual environment. They restore the previous value of the ENV_VARIABLE.

deactivate () {
    ... # Already existing code

    # Restore the previous value of the ENV_VARIABLE on deactivation
    # This code is executed when `deactivate` alias is called.
    if [ ! "${1:-}" = "nondestructive" ] ; then
        if [ -n "${_OLD_ENV_VARIABLE:-}" ] ; then
            ENV_VARIABLE="${_OLD_ENV_VARIABLE:-}"
            export ENV_VARIABLE
            unset _OLD_ENV_VARIABLE
        else
            unset ENV_VARIABLE
        fi
    fi

}
  1. At the end of the script add lines, where you define the "new value of the ENV_VARIABLE".

These lines are executed when you activate the virtual environment.

# Update or set a ENV_VARIABLE on activation
if [ -n "${ENV_VARIABLE:-}" ] ; then
    _OLD_ENV_VARIABLE="${ENV_VARIABLE:-}"
fi
export ENV_VARIABLE="new value of the ENV_VARIABLE"

  1. Save an close the file.

OUTCOME:

Result of setting a new environment variable:

:~$ echo $ENV_VARIABLE

:~$

:~$ source MY_ENV/bin/activate
(MY_ENV):~$

(MY_ENV):~$ echo $ENV_VARIABLE
new value of the ENV_VARIABLE
:~$

(MY_ENV):~$ deactivate
:~$

:~$ echo $ENV_VARIABLE

:~$


Result of updating already existing environment variable:

:~$ export ENV_VARIABLE = "old value of the ENV_VARIABLE"
:~$

:~$ echo $ENV_VARIABLE
old value of the ENV_VARIABLE
:~$

:~$ source MY_ENV/bin/activate
(MY_ENV):~$

(MY_ENV):~$ echo $ENV_VARIABLE
new value of the ENV_VARIABLE
:~$

(MY_ENV):~$ deactivate
:~$

:~$ echo $ENV_VARIABLE
old value of the ENV_VARIABLE
:~$

Answered By: Grzegorz