diff options
Diffstat (limited to 'configlib/model.py')
-rw-r--r-- | configlib/model.py | 85 |
1 files changed, 72 insertions, 13 deletions
diff --git a/configlib/model.py b/configlib/model.py index 6d79464..5f5c694 100644 --- a/configlib/model.py +++ b/configlib/model.py @@ -1,41 +1,100 @@ +""" +Abstract models and classes for the config + +""" + import json +import os from abc import abstractmethod, ABC -from typing import TypeVar, Type, Union, AnyStr, TextIO +from typing import Type, Union, AnyStr, TextIO -_T = TypeVar('_T', bound='Config') +from configlib.util import snake_case class InvalidConfigTypingException(Exception): - pass + """ + The typing found in the given class is missing arguments. + Example: + + >>> import typing + >>> someting: typing.List[str, int] + + is illegal since :class:`typing.List` only takes one argument. + """ class ConfigValueMissingException(Exception): - pass + """ + The given config file is missing an argument + """ class Config(ABC): + """ + Base class for a Config. Do NOT extend this. use :class:`configlib.BaseConfig` instead. + + """ @classmethod @abstractmethod def get_name(cls) -> str: - pass + """ + Get the name for a config + + :return: the name + """ @classmethod @abstractmethod - def parse_dict(cls: Type[_T], data: dict) -> _T: - pass + def parse_dict(cls: Type['Config'], data: dict) -> 'Config': + """ + For the given data return the config instance. + + :param data: the loaded data dict + :return: a loaded config + """ @classmethod - def load(cls: Type[_T], file: Union[AnyStr, TextIO]) -> _T: + def load(cls: Type['Config'], file: Union[AnyStr, TextIO]) -> 'Config': + """ + Load a specified config file + + :param file: the file object or file path + :return: the parsed config according to :func:`.parse_dict` + """ if hasattr(file, 'read'): return cls.loads(file.read()) - with open(file) as fp: - return cls.load(fp) + with open(file) as file_pointer: + return cls.load(file_pointer) @classmethod - def loads(cls: Type[_T], text: str) -> _T: + def loads(cls: Type['Config'], text: str) -> 'Config': + """ + Load data from text + + :param text: the text data + :return: the parsed config + """ return cls.parse_dict(json.loads(text)) @classmethod - def get_instance(cls: Type[_T]) -> _T: - return cls + def get_instance(cls: Type['Config']) -> 'Config': + """ + get a Config instance according to the matching environment variable + + :return: the parsed config + """ + name = os.environ.get(snake_case(cls.get_name()), '').strip() + return cls.get_instance_for_env(name) + + @classmethod + def get_instance_for_env(cls: Type['Config'], env: str) -> 'Config': + """ + get a Config instance for a given environment + + :param env: the wanted environment + :return: the parsed config + """ + if env: + env = '-' + env + return cls.load('config/' + snake_case(cls.get_name()) + env + '.json') |