feat: add WuttaConfigProfile base class
convenience for use with various configurable features/services etc.
This commit is contained in:
parent
a721e63275
commit
ad6a3377ab
2 changed files with 105 additions and 1 deletions
|
@ -1013,3 +1013,89 @@ def make_config(
|
|||
extension.startup(config)
|
||||
|
||||
return config
|
||||
|
||||
|
||||
class WuttaConfigProfile:
|
||||
"""
|
||||
Base class to represent a configured "profile" in the context of
|
||||
some service etc.
|
||||
|
||||
:param config: App :term:`config object`.
|
||||
|
||||
:param key: Config key for the profile.
|
||||
|
||||
Generally each subclass will represent a certain type of config
|
||||
profile, and each instance will represent a single profile
|
||||
(identified by the ``key``).
|
||||
"""
|
||||
|
||||
def __init__(self, config, key):
|
||||
self.config = config
|
||||
self.app = self.config.get_app()
|
||||
self.key = key
|
||||
self.load()
|
||||
|
||||
@property
|
||||
def section(self):
|
||||
"""
|
||||
The primary config section under which profiles may be
|
||||
defined.
|
||||
|
||||
There is no default; each subclass must declare it.
|
||||
|
||||
This corresponds to the typical INI file section, for instance
|
||||
a section of ``wutta.telemetry`` assumes file contents like:
|
||||
|
||||
.. code-block:: ini
|
||||
|
||||
[wutta.telemetry]
|
||||
default.submit_url = /nodes/telemetry
|
||||
special.submit_url = /nodes/telemetry-special
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def load(self):
|
||||
"""
|
||||
Read all relevant settings from config, and assign attributes
|
||||
on the profile instance accordingly.
|
||||
|
||||
There is no default logic but subclass will generally override.
|
||||
|
||||
While a caller can use :meth:`get_str()` to obtain arbitrary
|
||||
config values dynamically, it is often useful for the profile
|
||||
to pre-load some config values. This allows "smarter"
|
||||
interpretation of config values in some cases, and at least
|
||||
ensures common/shared logic.
|
||||
|
||||
There is no constraint or other guidance in terms of which
|
||||
profile attributes might be set by this method. Subclass
|
||||
should document if necessary.
|
||||
"""
|
||||
|
||||
def get_str(self, option, **kwargs):
|
||||
"""
|
||||
Get a string value for the profile, from config.
|
||||
|
||||
:param option: Name of config option for which to return value.
|
||||
|
||||
This just calls :meth:`~WuttaConfig.get()` on the config
|
||||
object, but for a particular setting name which it composes
|
||||
dynamically.
|
||||
|
||||
Assuming a config file like:
|
||||
|
||||
.. code-block:: ini
|
||||
|
||||
[wutta.telemetry]
|
||||
default.submit_url = /nodes/telemetry
|
||||
|
||||
Then a ``default`` profile under the ``wutta.telemetry``
|
||||
section would effectively have a ``submit_url`` option::
|
||||
|
||||
class TelemetryProfile(WuttaConfigProfile):
|
||||
section = "wutta.telemetry"
|
||||
|
||||
profile = TelemetryProfile("default")
|
||||
url = profile.get_str("submit_url")
|
||||
"""
|
||||
return self.config.get(f'{self.section}.{self.key}.{option}', **kwargs)
|
||||
|
|
|
@ -12,7 +12,7 @@ from wuttjamaican import conf as mod
|
|||
from wuttjamaican import conf
|
||||
from wuttjamaican.exc import ConfigurationError
|
||||
from wuttjamaican.app import AppHandler
|
||||
from wuttjamaican.testing import FileTestCase
|
||||
from wuttjamaican.testing import FileTestCase, ConfigTestCase
|
||||
|
||||
|
||||
class TestWuttaConfig(FileTestCase):
|
||||
|
@ -867,3 +867,21 @@ class TestMakeConfig(FileTestCase):
|
|||
foo_cls.assert_called_once_with()
|
||||
foo_obj.configure.assert_called_once_with(testconfig)
|
||||
foo_obj.startup.assert_called_once_with(testconfig)
|
||||
|
||||
|
||||
class TestWuttaConfigProfile(ConfigTestCase):
|
||||
|
||||
def make_profile(self, key):
|
||||
return mod.WuttaConfigProfile(self.config, key)
|
||||
|
||||
def test_section(self):
|
||||
profile = self.make_profile('default')
|
||||
self.assertRaises(NotImplementedError, getattr, profile, 'section')
|
||||
|
||||
def test_get_str(self):
|
||||
self.config.setdefault('wutta.telemetry.default.submit_url', '/nodes/telemetry')
|
||||
with patch.object(mod.WuttaConfigProfile, 'section', new='wutta.telemetry'):
|
||||
profile = self.make_profile('default')
|
||||
self.assertEqual(profile.section, 'wutta.telemetry')
|
||||
url = profile.get_str('submit_url')
|
||||
self.assertEqual(url, '/nodes/telemetry')
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue