aboutsummaryrefslogtreecommitdiff
path: root/configlib/model.py
diff options
context:
space:
mode:
Diffstat (limited to 'configlib/model.py')
-rw-r--r--configlib/model.py85
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')