Skip to content
Snippets Groups Projects
Commit ea2a4883 authored by plup's avatar plup
Browse files

feat: cached settings resolution at init

parent 107c1224
No related branches found
No related tags found
2 merge requests!167Add python code in settings,!158Load djangoldp conguration from YAML file
......@@ -21,8 +21,9 @@ def configure(filename='settings.yml'):
"""Helper function to configure django from LDPSettings."""
# ref: https://docs.djangoproject.com/fr/2.2/topics/settings/#custom-default-settings
settings = LDPSettings(path=filename)
django_settings.configure(settings) # gives a LazySettings
ldpsettings = LDPSettings(path=filename)
django_settings.configure(ldpsettings)
class LDPSettings(object):
......@@ -36,6 +37,7 @@ class LDPSettings(object):
self.path = path
self._config = None
self._settings = self.build_settings()
@property
def config(self):
......@@ -65,12 +67,12 @@ class LDPSettings(object):
# import from an installed package
mod = import_module(f'{pkg}.djangoldp_settings')
logger.debug(f'Settings found for {pkg} in a installed package')
except (ModuleNotFoundError):
except ModuleNotFoundError:
try:
# import from a local packages in a subfolder (same name the template is built this way)
mod = import_module(f'{pkg}.{pkg}.djangoldp_settings')
logger.debug(f'Settings found for {pkg} in a local package')
except (ModuleNotFoundError):
except ModuleNotFoundError:
logger.debug(f'No settings found for {pkg}')
break
......@@ -78,12 +80,64 @@ class LDPSettings(object):
try:
attr.extend(getattr(mod, attributes))
logger.debug(f'{attributes} found in local package {pkg}')
except (NameError):
except NameError:
logger.info(f'No {attributes} found for package {pkg}')
pass
return attr
def build_settings(self):
"""
Look for the parameter in config. Each step override the value of the previous key found.
Resolution order of the configuration:
1. Core default settings
2. Packages settings
3. Code from a local settings.py file
4. YAML config file
"""
# start from default core settings
settings = global_settings.__dict__
logger.debug(f'building settings from core defaults')
# look settings from packages in the order they are given (local override installed)
for pkg in self.DJANGOLDP_PACKAGES:
try:
# override with values from installed package
mod = import_module(f'{pkg}.djangoldp_settings')
settings.update({k: v for k, v in mod.__dict__.items() if not k.startswith('_')})
logger.debug(f'updating settings from installed package {pkg}')
except ModuleNotFoundError:
pass
try:
# override with values from local package
mod = import_module(f'{pkg}.{pkg}.djangoldp_settings')
settings.update({k: v for k, v in mod.__dict__.items() if not k.startswith('_')})
logger.debug(f'updating settings from local package {pkg}')
except ModuleNotFoundError:
pass
# look in settings.py file in directory
try:
mod = import_module('settings')
settings.update({k: v for k, v in mod.__dict__.items() if not k.startswith('_')})
logger.debug(f'updating settings from local settings.py file')
except ModuleNotFoundError:
pass
# look in YAML config file 'server' section
try:
conf = self.config.get('server', {})
settings.update({k: v for k, v in conf.items() if not k.startswith('_')})
logger.debug(f'updating settings with project config')
except KeyError:
pass
return settings
@property
def DJANGOLDP_PACKAGES(self):
......@@ -124,54 +178,10 @@ class LDPSettings(object):
return middlewares
def __getattr__(self, param):
"""
Look for the parameter in config and return the first value found.
Resolution order of the configuration:
1. YAML config file
2. Packages settings
3. Core default settings
"""
if not param.startswith('_') and param.isupper():
# look in config file
try:
value = self.config['server'][param]
logger.debug(f'{param} found in project config')
return value
except KeyError:
pass
# look in all packages config
for pkg in self.DJANGOLDP_PACKAGES:
try:
# import from local package
mod = import_module(f'{pkg}.{pkg}.djangoldp_settings')
value = getattr(mod, param)
logger.debug(f'{param} found in local package {pkg}')
return value
except (ModuleNotFoundError, NameError, AttributeError):
pass
try:
# import from installed package
mod = import_module(f'{pkg}.djangoldp_settings')
value = getattr(mod, param)
logger.debug(f'{param} found in installed package {pkg}')
return value
except (ModuleNotFoundError, NameError, AttributeError):
pass
# look in default settings
try:
value = getattr(global_settings, param)
logger.debug(f'{param} found in core default config')
return value
except AttributeError:
pass
"""Return the requested parameter from cached settings."""
try:
return self._settings[param]
except KeyError:
# raise the django exception for inexistent parameter
raise AttributeError(f'no "{param}" parameter found in settings')
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment