Forums

Using variables in virtual environment

I've started using a separate virtualenv for my project with virtualenvwrapper. I also loaded my variables into the /home/leapfrog/.virtualenvs/myenv/bin/postactivate and restarted my app. Everything seems fine and my app works just as before. I can 'workon' my environment and echo the environment variables. In my configurations I can also print out the variables like so

import os

class Config(object):
    DEBUG = False
    TESTING = False
    SECRET_KEY = 'hard coded secret key'
    print os.getenv('SECRET_KEY')

class ProductionConfig(Config):
    DATABASE_URI = 'mysql://user@localhost/foo'

and it will print out the appropriate SECRET_KEY for my virtualenv (not the hard coded SECRET_KEY).

    >>>  virtualenv secret key

. However when I want to actually assign the SECRET_KEY in my virtualenv to my configuration settings like so:

import os

class Config(object):
        DEBUG = False
        TESTING = False
        SECRET_KEY = os.getenv('SECRET_KEY')

    class ProductionConfig(Config):
        DATABASE_URI = 'mysql://user@localhost/foo'

The SECRET_KEY will fail to be loaded into the app configuration and I'll receive this error in my stack trace:

RuntimeError: the session is unavailable because no secret key was set.  Set the secret_key on the application to something unique and secret.

So, if I can print out the variables in my virtualenv in my console as well as my configuration file, but can't assign them what exactly am I getting wrong?

That's interesting. It sounds like environment variables that you set in the postactivate script don't get applied to web apps. That makes some kind of sense -- there's a similar problem with environment variables that are set in the .bashrc file.

The best workaround is probably to set the variables in your web app's WSGI file using os.environ["SECRET_KEY"] = "the value"

This file? /var/www/www_my_app_wsgi.py

And something like this:

# import flask app but need to call it "application" for WSGI to work
from manage import app as application
os.environ["SECRET_KEY"] = "the new secret key value"

In my config file os.getenv('SECRET_KEY') still references the virtualenv SECRET_KEY.

Any thoughts?

It should probably be before the import app line.

That doesn't seem to work either. Hmmm. I guess I'll fiddle around a little more.

Its working now with @giles suggestion. If anyone stumbles upon this here is what I did...

  1. Deleted the virtualenv in the command line

    rmvirtualenv myenv
    
  2. Removed the path in my dashboard's virtualenv settings

  3. Inside my WSGI configuration file (linked in the dashboard) I set the variables like so

    import os
    os.environ['SECRET_KEY'] = 'my secret key'
    
    [... all of the other WSGI config stuff below ... ]
    
  4. Then in any file in the app, mainly in the configuration file the environment variables may be referenced like I originally intended:

    import os
    
    class Config(object):
        DEBUG = False
        TESTING = False
        SECRET_KEY = os.getenv('SECRET_KEY')
    
    class ProductionConfig(Config):
        DATABASE_URI = 'mysql://user@localhost/foo'
    

That'll work! If you need those environment variables in your Bash console sessions as well, you can duplicate them in ~/.virtualenvs/venv-name/bin/postactivate

Good to know. Thanks for the tip!