Last active
April 21, 2016 16:30
-
-
Save Klortho/273335612b427fc9482a34c01e0911cb to your computer and use it in GitHub Desktop.
SettingsDeferrer - one way to implement lazy settings with overrides, in Django
This file contains 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
#!/usr/bin/env python | |
from os import path, getenv | |
import settings_deferrer as s | |
# Put normal settings here, if you want, or put them all into the `fill_defaults()` | |
# function below. If the latter, though, you'll have to use the `s.MY_SETTING` syntax. | |
MY_SETTING = 'zormulon' | |
# ... | |
# This function is executed later, after the overrides are brought in. It defines | |
# all of the *default* settings, any of which can be overridden, even if they are | |
# dependent on each other. | |
def fill_defaults(): | |
# Here's the default for the `JIG_BASE` setting. | |
s.JIG_BASE = 'https://www.ncbi.nlm.nih.gov' | |
# Default for `JIG_VERSION` -- we'll override this | |
s.JIG_VERSION = '1.14.7' | |
# Default for computing `JIG_URL` from previously-defined settings. In a naive settings.py, | |
# you wouldn't be able to override JIG_VERSION in this statement -- it would use the value | |
# just assigned above. | |
# This works by proxying through getters and setters in the `s` object. This was as clean | |
# a syntax as I was able to come up with. | |
s.JIG_URL = s.JIG_BASE + '/core/jig/' + s.JIG_VERSION + '/js/jig.min.js' | |
# Here we override JIG_VERSION. This is where we'd use settings_overrider to get values | |
# from yaml or env. vars. | |
JIG_VERSION = '2.5' | |
# This method finishes filling in everything | |
s.config(globals(), fill_defaults) | |
print('Final settings: ') | |
print(' JIG_BASE: ' + JIG_BASE) | |
print(' JIG_VERSION: ' + JIG_VERSION) | |
print(' JIG_URL: ' + JIG_URL) |
This file contains 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
import sys | |
class SettingsDeferrer(object): | |
# Direct get, private: | |
def _get(self, name): | |
d = self.__dict__ | |
return d[name] if name in d else None | |
def _set(self, name, value): | |
self.__dict__[name] = value | |
# If an overrides value is set, return that; otherwise, return | |
# the default | |
def __getattr__(self, name): | |
merged = self._get('merged') | |
v = merged[name] if (merged and name in merged) else None | |
return v | |
# This gets called from within fill_defaults. It only sets the value in | |
# `merged` if there isn't something there already | |
def __setattr__(self, name, value): | |
merged = self._get('merged') | |
if not(merged): return | |
if not(name in merged): merged[name] = value | |
def config(self, _overrides, fill_defaults): | |
self._set('merged', _overrides) | |
fill_defaults() | |
this = SettingsDeferrer() | |
sys.modules[__name__] = this |
This file contains 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
Django~=1.9.0 | |
settings-overrider~=0.5 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment