Source code for pyzeal.settings.json_helper

"""
TODO.

Authors:\n
- Philipp Schuette\n
"""

from json import JSONDecodeError, dump, load
from typing import Dict, Literal, Set, Tuple, Type, Union

from pyzeal.pyzeal_logging.log_levels import LogLevel
from pyzeal.pyzeal_types.algorithm_types import AlgorithmTypes
from pyzeal.pyzeal_types.container_types import ContainerTypes
from pyzeal.pyzeal_types.estimator_types import EstimatorTypes
from pyzeal.settings.invalid_setting_exception import InvalidSettingException

# admissible keys when changing settings
tCoreSettingsKey = Union[
    Literal["defaultContainer"],
    Literal["defaultAlgorithm"],
    Literal["defaultEstimator"],
]
tSettingsKey = Union[
    Literal["logLevel"],
    Literal["verbose"],
    Literal["precision"],
]
# admissible types when assigning to settings properties
tCoreSettingsPropertyType = Union[
    ContainerTypes, AlgorithmTypes, EstimatorTypes
]
tSettingsPropertyType = Union[LogLevel, bool, Tuple[int, int]]


[docs] class JSONHelper: """ Static helper class providing methods to read and manipulate json settings. """ _coreSettings: Dict[ tCoreSettingsKey, Union[ Type[AlgorithmTypes], Type[ContainerTypes], Type[EstimatorTypes] ], ] = { "defaultAlgorithm": AlgorithmTypes, "defaultContainer": ContainerTypes, "defaultEstimator": EstimatorTypes, } _settings: Set[tSettingsKey] = {"logLevel", "verbose", "precision"}
[docs] @staticmethod def createOrUpdateCoreSetting( filename: str, setting: tCoreSettingsKey, value: tCoreSettingsPropertyType, ) -> None: """ Update a core setting or create a new one if no value had previously been set. :param filename: the json file to update :param setting: setting to create or update :param value: New setting value :raises InvalidSettingException: If the given value is invalid for the specified setting, an `InvalidSettingException` is raised. """ currentSettings: Dict[tCoreSettingsKey, str] = {} try: with open(filename, "r", encoding="utf-8") as custom: currentSettings = load(custom) except FileNotFoundError: pass except JSONDecodeError as exc: raise InvalidSettingException(f"{filename=}") from exc if setting in JSONHelper._coreSettings: if not isinstance(value, JSONHelper._coreSettings[setting]): raise InvalidSettingException(setting) currentSettings[setting] = value.value else: raise InvalidSettingException(f"key={setting}") with open(filename, "w", encoding="utf-8") as custom: dump(currentSettings, custom, indent=4)
[docs] @staticmethod def loadCoreSettingsFromFile( filename: str, settings: Dict[str, str] ) -> None: """ Load the settings stored in `filename` into `settings`. :param filename: Settings file to load :param settings: Dict to store the read settings in """ try: with open(filename, "r", encoding="utf-8") as settingsFile: for key, value in load(settingsFile).items(): if key not in JSONHelper._coreSettings: continue settings[key] = value except FileNotFoundError: pass
[docs] @staticmethod def createOrUpdateSetting( filename: str, setting: tSettingsKey, value: tSettingsPropertyType ) -> None: """ Update a setting or create a new setting if no value has been set yet. :param filename: the json file to update :param setting: setting to create or update :param value: New setting value :raises InvalidSettingException: If the given value is invalid for the specified setting, an `InvalidSettingException` is raised. """ currentSettings: Dict[ tSettingsKey, Union[str, bool, Tuple[int, int]] ] = {} try: with open(filename, "r", encoding="utf-8") as custom: currentSettings = load(custom) except FileNotFoundError: pass except JSONDecodeError as exc: raise InvalidSettingException(f"{filename=}") from exc if setting == "logLevel": if not isinstance(value, LogLevel): raise InvalidSettingException("default algorithm") currentSettings["logLevel"] = value.name elif setting == "verbose": if not isinstance(value, bool): raise InvalidSettingException("default verbosity") currentSettings["verbose"] = value elif setting == "precision": if not ( isinstance(value, tuple) and isinstance(value[0], int) and isinstance(value[1], int) ): raise InvalidSettingException("default precision") currentSettings["precision"] = (value[0], value[1]) else: raise InvalidSettingException(f"key={setting}") with open(filename, "w", encoding="utf-8") as custom: dump(currentSettings, custom, indent=4)
[docs] @staticmethod def loadSettingsFromFile( filename: str, settings: Dict[str, Union[str, bool, Tuple[int, int]]] ) -> None: """ Load the settings stored in `filename` into `settings`. :param filename: File to load :param settings: Dict to store the read settings in """ try: with open(filename, "r", encoding="utf-8") as settingsFile: for key, value in load(settingsFile).items(): if key not in JSONHelper._settings: continue if isinstance(value, list): value = tuple(value) settings[key] = value except FileNotFoundError: pass