1
0
mirror of https://github.com/vladmandic/sdnext.git synced 2026-01-29 05:02:09 +03:00
Files
sdnext/scripts/lbm/config.py
Vladimir Mandic 2b9056179d add lbm background replace with relightining
Signed-off-by: Vladimir Mandic <mandic00@live.com>
2025-07-04 15:33:16 -04:00

141 lines
4.2 KiB
Python

import json
import os
import warnings
from dataclasses import asdict, field
from typing import Any, Dict, Union
import yaml
from pydantic import ValidationError
from pydantic.dataclasses import dataclass
from yaml import safe_load
@dataclass
class BaseConfig:
"""This is the BaseConfig class which defines all the useful loading and saving methods
of the configs"""
name: str = field(init=False)
def __post_init__(self):
self.name = self.__class__.__name__
@classmethod
def from_dict(cls, config_dict: Dict[str, Any]) -> "BaseConfig":
"""Creates a BaseConfig instance from a dictionnary
Args:
config_dict (dict): The Python dictionnary containing all the parameters
Returns:
:class:`BaseConfig`: The created instance
"""
try:
config = cls(**config_dict)
except (ValidationError, TypeError) as e:
raise e
return config
@classmethod
def _dict_from_json(cls, json_path: Union[str, os.PathLike]) -> Dict[str, Any]:
try:
with open(json_path) as f:
try:
config_dict = json.load(f)
return config_dict
except (TypeError, json.JSONDecodeError) as e:
raise TypeError(
f"File {json_path} not loadable. Maybe not json ? \n"
f"Catch Exception {type(e)} with message: " + str(e)
) from e
except FileNotFoundError:
raise FileNotFoundError(
f"Config file not found. Please check path '{json_path}'"
)
@classmethod
def from_json(cls, json_path: str) -> "BaseConfig":
"""Creates a BaseConfig instance from a JSON config file
Args:
json_path (str): The path to the json file containing all the parameters
Returns:
:class:`BaseConfig`: The created instance
"""
config_dict = cls._dict_from_json(json_path)
config_name = config_dict.pop("name")
if cls.__name__ != config_name:
warnings.warn(
f"You are trying to load a "
f"`{ cls.__name__}` while a "
f"`{config_name}` is given."
)
return cls.from_dict(config_dict)
def to_dict(self) -> dict:
"""Transforms object into a Python dictionnary
Returns:
(dict): The dictionnary containing all the parameters"""
return asdict(self)
def to_json_string(self):
"""Transforms object into a JSON string
Returns:
(str): The JSON str containing all the parameters"""
return json.dumps(self.to_dict())
def save_json(self, file_path: str):
"""Saves a ``.json`` file from the dataclass
Args:
file_path (str): path to the file
"""
with open(os.path.join(file_path), "w", encoding="utf-8") as fp:
fp.write(self.to_json_string())
def save_yaml(self, file_path: str):
"""Saves a ``.yaml`` file from the dataclass
Args:
file_path (str): path to the file
"""
with open(os.path.join(file_path), "w", encoding="utf-8") as fp:
yaml.dump(self.to_dict(), fp)
@classmethod
def from_yaml(cls, yaml_path: str) -> "BaseConfig":
"""Creates a BaseConfig instance from a YAML config file
Args:
yaml_path (str): The path to the yaml file containing all the parameters
Returns:
:class:`BaseConfig`: The created instance
"""
with open(yaml_path, "r") as f:
try:
config_dict = safe_load(f)
except yaml.YAMLError as e:
raise yaml.YAMLError(
f"File {yaml_path} not loadable. Maybe not yaml ? \n"
f"Catch Exception {type(e)} with message: " + str(e)
) from e
config_name = config_dict.pop("name")
if cls.__name__ != config_name:
warnings.warn(
f"You are trying to load a "
f"`{ cls.__name__}` while a "
f"`{config_name}` is given."
)
return cls.from_dict(config_dict)