Last active
December 14, 2015 20:28
-
-
Save drinks/5143901 to your computer and use it in GitHub Desktop.
Django local_settings made friendly with Foreman's .env file
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
## | |
# appname/management/commands/exportenv.py | |
# | |
import re | |
import json | |
import sys | |
import StringIO | |
from importlib import import_module | |
from optparse import make_option | |
from django.core.management.base import BaseCommand | |
class Command(BaseCommand): | |
help = '''Serializes individual settings items into json-safe | |
strings suitable for dumping into a .env for Foreman.''' | |
option_list = BaseCommand.option_list + ( | |
make_option('--settings-module', | |
action='store', | |
dest='settings_module', | |
default='local_settings', | |
help='''The name of the local settings module to | |
export. Default is local_settings'''), | |
make_option('--outfile', | |
action='store', | |
dest='outfile', | |
default='.env', | |
help='''The name of the file to write. Set to None | |
to print to stdout. Default is .env'''), | |
make_option('--include-databases', | |
action='store_true', | |
dest='include_databases', | |
default=False, | |
help='''Whether or not to include the databases | |
dict in env output. Default is False.'''), | |
) | |
VALID_SETTING = re.compile(r'^[A-Z][A-Z0-9_]+$') | |
def handle(self, *args, **options): | |
flo = StringIO.StringIO() | |
failed_settings = [] | |
local_settings = import_module(options.get('settings_module')) | |
settings_d = local_settings.__dict__ | |
for setting, value in settings_d.iteritems(): | |
if not self.VALID_SETTING.search(setting): | |
continue | |
# Skip databases if not flagged to include them | |
if setting == u"DATABASES" and not options.get('include_databases'): | |
continue | |
try: | |
flo.write(u"%s=%s\n" % (setting, json.dumps(value, default=self.__class__._datehandler))) | |
except Exception, e: | |
failed_settings.append("%s: %s" % (setting, e)) | |
if options.get('outfile', 'None') != 'None': | |
with open(options.get('outfile'), 'w+') as fp: | |
fp.write(flo.getvalue()) | |
else: | |
sys.stdout.write(flo.getvalue()) | |
if len(failed_settings): | |
sys.stderr.write('\nFailed to parse some settings:\n') | |
sys.stderr.write('\n'.join(failed_settings)) | |
flo.close() | |
@staticmethod | |
def _datehandler(obj): | |
if hasattr(obj, 'isoformat'): | |
return obj.isoformat() | |
else: | |
raise TypeError, 'Object of type %s with value of %s is not JSON serializable' % (type(obj), repr(obj)) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Add dj_database_url to your requirements.txt | |
import os | |
import re | |
import json | |
import sys | |
# All your non-local settings go here... | |
if 'DEBUG' in os.environ.keys(): | |
# Load .env file and | |
# Parse database configuration from $DATABASE_URL | |
import dj_database_url | |
DATABASES = {} | |
DATABASES['default'] = dj_database_url.config() | |
# Honor the 'X-Forwarded-Proto' header for request.is_secure() | |
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') | |
for setting, value in os.environ.iteritems(): | |
if re.search(r'^[A-Z][A-Z0-9_]+$', setting): | |
# Loading as json will fail if the value is a simple string | |
try: | |
setattr(sys.modules[__name__], setting, json.loads(value)) | |
except: | |
setattr(sys.modules[__name__], setting, value) | |
else: | |
try: | |
from local_settings import * | |
except ImportError, e: | |
print """Caught %s trying to import local_settings. Please make sure | |
local_settings.py exists and is free of errors. | |
""" | |
raise |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment