Accessing environment variables with a magic module.
>>> import os >>> from envcfg.raw.python import CONFIGURE_OPTS >>> >>> CONFIGURE_OPTS '--enable-shared --enable-universalsdk=/ --with-universal-archs=intel' >>> CONFIGURE_OPTS == os.environ['PYTHON_CONFIGURE_OPTS'] True
It works with many frameworks such as Django and Flask. Then you can store your config in the environment variables instead of framework-specific config files. It is recommended by 12-Factor.
$ pip install python-envcfg
import envcfg.raw.foo as config
: Import eachFOO_*
environment variable as string.import envcfg.json.foo as config
: Import eachFOO_*
environment variable as JSON body.import envcfg.smart.foo as config
: Try to import eachFOO_*
environment variable as JSON body, if fail then import it as string.
There is an example:
envcfg.raw.foo.VAL |
envcfg.json.foo.VAL |
envcfg.smart.foo.VAL |
|
---|---|---|---|
FOO_VAL=foo |
'foo' |
ImportError |
'foo' |
FOO_VAL="foo" |
'"foo"' |
'foo' |
'foo' |
FOO_VAL=42 |
'42' |
42 |
42 |
FOO_VAL="42" |
'"42"' |
'42' |
'42' |
Defines environment variables with a prefix:
$ cat .env # should not checked into VCS # values are valid JSON expressions MYAPP_DEBUG=true MYAPP_SECRET_KEY='"7950ad141c7e4b3990631fcdf9a1d909"' MYAPP_SQLALCHEMY_DATABASE_URI='"sqlite:///tmp/myapp.sqlite3"'
Creates Flask app and loads config from python-envcfg:
$ cat myapp.py ... app = Flask(__name__) app.config.from_object('envcfg.json.myapp') # MYAPP_ -> .myapp ...
Enters your app with those environment variables:
$ env $(cat .env | xargs) python myapp.py
Creates a django project and moves all sensitive config items into the environment variables:
$ cat djapp/settings.py # codebase-scope config ... INSTALLED_APPS = ( 'django.contrib.admin', ) ... $ cat .env # environment-scope config, should not checked into VCS # values are valid JSON expressions DJAPP_SECRET_KEY='"wo9g2o#jws=u"' DJAPP_DEBUG=true DJAPP_TEMPLATE_DEBUG=true
Adds importing statements in the end of
settings.py
module:$ tail -n 2 djapp/settings.py # importing all config items stored in the environment variables from envcfg.json.djapp import * # noqa
Runs your Django app with environment variables:
$ env $(cat .env | xargs) python manage.py runserver
Defines environment variables with a prefix:
$ cat .env export TORAPP_PORT='8888' export TORAPP_MYSQL_HOST='"127.0.0.1"' export TORAPP_MYSQL_DATABASE='"database"'
Creates a Tornado project and loads config:
$ cat torapp/server.py from tornado.web import Application, RequestHandler from tornado.ioloop import IOLoop from tornado.options import define, options from tordb import Connection def options_from_object(*args, **kwargs): module = __import__(*args, **kwargs) for name, value in vars(module).items(): name = name.lower() if name in options._options: options._options[name].set(value) class IndexHandler(RequestHandler): def initialize(self): self.db = Connection(options.mysql_host, options.mysql_database) def get(self): pass # some database operations with ``self.db`` application = Application([ (r'/', IndexHandler), ]) define('port', type=int) define('mysql_host', type=unicode) define('mysql_database', type=unicode) options_from_object('envcfg.json.torapp', fromlist=['torapp']) if __name__ == '__main__': application.listen(options.port) IOLoop.instance().start()
Runs your Tornado app:
$ env $(cat .env | xargs) python server.py
In development, we can work with per-project environments but no more typing
source foo/bar
.
I recommend to put your project-specified environment variables in
{PROJECT_ROOT}/.env
and mark the .env
as ignored in your VCS. For
example, you can write /.env
in .gitignore
if you are using Git, and
put a .env.example
as a copying template for new-cloned projects.
And then, you can use some utility such as honcho or autoenv to apply
the .env
automatically.
For honcho:
$ echo 'MYPROJECT_DEBUG=true' >> .env $ echo 'web: python manage.py runserver' >> Procfile $ honcho run python manage.py check-debug True $ honcho start web Starting development server at http://127.0.0.1:5000/ ...
For autoenv:
$ echo 'MYPROJECT_DEBUG=true' >> myproject/.env $ cd myproject $ python manage.py check-debug True $ python manage.py runserver Starting development server at http://127.0.0.1:5000/ ...
If you want to report bugs or request features, please create issues on GitHub Issues.