summaryrefslogtreecommitdiff
path: root/src/home/config/config.py
diff options
context:
space:
mode:
authorEvgeny Zinoviev <me@ch1p.io>2023-06-10 21:54:56 +0300
committerEvgeny Zinoviev <me@ch1p.io>2023-06-10 21:55:01 +0300
commit327a5298359027099631c3c9967b7585928cd367 (patch)
treefb6358ceb3182c285bce3cff392654b0538c2c5c /src/home/config/config.py
parentf29e139cbb7e4a4d539cba6e894ef4a6acd312d6 (diff)
port relay_mqtt_http_proxy to new config scheme; config: support addr types & normalization
Diffstat (limited to 'src/home/config/config.py')
-rw-r--r--src/home/config/config.py61
1 files changed, 40 insertions, 21 deletions
diff --git a/src/home/config/config.py b/src/home/config/config.py
index aef9ee7..dc00d2e 100644
--- a/src/home/config/config.py
+++ b/src/home/config/config.py
@@ -1,10 +1,10 @@
import yaml
import logging
import os
-import pprint
+import cerberus
+import cerberus.errors
from abc import ABC
-from cerberus import Validator, DocumentError
from typing import Optional, Any, MutableMapping, Union
from argparse import ArgumentParser
from enum import Enum, auto
@@ -12,11 +12,20 @@ from os.path import join, isdir, isfile
from ..util import Addr
+class MyValidator(cerberus.Validator):
+ def _normalize_coerce_addr(self, value):
+ return Addr.fromstring(value)
+
+
+MyValidator.types_mapping['addr'] = cerberus.TypeDefinition('Addr', (Addr,), ())
+
+
CONFIG_DIRECTORIES = (
join(os.environ['HOME'], '.config', 'homekit'),
'/etc/homekit'
)
+
class RootSchemaType(Enum):
DEFAULT = auto()
DICT = auto()
@@ -95,10 +104,19 @@ class ConfigUnit(BaseConfigUnit):
raise IOError(f'\'{name}.yaml\' not found')
- @staticmethod
- def schema() -> Optional[dict]:
+ @classmethod
+ def schema(cls) -> Optional[dict]:
return None
+ @classmethod
+ def _addr_schema(cls, required=False, **kwargs):
+ return {
+ 'type': 'addr',
+ 'coerce': Addr.fromstring,
+ 'required': required,
+ **kwargs
+ }
+
def validate(self):
schema = self.schema()
if not schema:
@@ -109,7 +127,7 @@ class ConfigUnit(BaseConfigUnit):
schema['logging'] = {
'type': 'dict',
'schema': {
- 'logging': {'type': 'bool'}
+ 'logging': {'type': 'boolean'}
}
}
@@ -125,27 +143,27 @@ class ConfigUnit(BaseConfigUnit):
except KeyError:
pass
+ v = MyValidator()
+
if rst == RootSchemaType.DICT:
- v = Validator({'document': {
- 'type': 'dict',
- 'keysrules': {'type': 'string'},
- 'valuesrules': schema
- }})
- result = v.validate({'document': self._data})
+ normalized = v.validated({'document': self._data},
+ {'document': {
+ 'type': 'dict',
+ 'keysrules': {'type': 'string'},
+ 'valuesrules': schema
+ }})['document']
elif rst == RootSchemaType.LIST:
- v = Validator({'document': schema})
- result = v.validate({'document': self._data})
+ v = MyValidator()
+ normalized = v.validated({'document': self._data}, {'document': schema})['document']
else:
- v = Validator(schema)
- result = v.validate(self._data)
- # pprint.pprint(self._data)
- if not result:
- # pprint.pprint(v.errors)
- raise DocumentError(f'{self.__class__.__name__}: failed to validate data:\n{pprint.pformat(v.errors)}')
+ normalized = v.validated(self._data, schema)
+
+ self._data = normalized
+
try:
self.custom_validator(self._data)
except Exception as e:
- raise DocumentError(f'{self.__class__.__name__}: {str(e)}')
+ raise cerberus.DocumentError(f'{self.__class__.__name__}: {str(e)}')
@staticmethod
def custom_validator(data):
@@ -238,7 +256,7 @@ class Config:
no_config=False):
global app_config
- if issubclass(name, AppConfigUnit) or name == AppConfigUnit:
+ if not isinstance(name, str) and not isinstance(name, bool) and issubclass(name, AppConfigUnit) or name == AppConfigUnit:
self.app_name = name.NAME
self.app_config = name()
app_config = self.app_config
@@ -278,6 +296,7 @@ class Config:
if not no_config:
self.app_config.load_from(path)
+ self.app_config.validate()
setup_logging(self.app_config.logging_is_verbose(),
self.app_config.logging_get_file(),