"""Package directory for TemporAI configuration."""importdataclassesimportosimportpathlibimportsysfromtypingimportTYPE_CHECKING,Callable,Set,Unionimporthydra.core.config_storeimportomegaconffromomegaconfimportOmegaConfimporttempor# NOTE: This config module is loaded before everything else, as other modules may use the config.DEFAULT_CONFIG_DIR="conf/tempor"DEFAULT_CONFIG_FILE_NAME="config"DEFAULT_CONFIG_FILE_PATH=os.path.join(os.path.dirname(__file__),f"{DEFAULT_CONFIG_DIR}/{DEFAULT_CONFIG_FILE_NAME}.yaml",)# --- Config structure. ---# Define the structure of the library config below.# Use missing for everything and define the defaults in the config file: DEFAULT_CONFIG_FILE_PATH.
[docs]@dataclasses.dataclassclassLoggingConfig:"""The configuration class for logging."""level:str=omegaconf.MISSING"""Logging level. One of: ``"DEBUG"``, ``"INFO"``, ``"WARNING"``, ``"ERROR"``, ``"CRITICAL"``."""diagnose:bool=omegaconf.MISSING"""Whether to use `loguru`'s ``diagnose`` setting for exceptions."""backtrace:bool=omegaconf.MISSING"""Whether to use `loguru`'s ``backtrace`` setting for exceptions."""file_log:bool=omegaconf.MISSING"""Whether to log to a file."""
[docs]@dataclasses.dataclassclassTemporConfig:"""The main configuration class for the TemporAI library."""logging:LoggingConfig"""Logging configuration."""working_directory:str=omegaconf.MISSING"""Working directory for the library. Can be set to a path string, ``"$PWD"``. or ``"~"``."""
[docs]defget_working_dir(self)->str:"""Get the working directory, with ``"$PWD"`` and ``"~"`` expanded. Returns: str: The working directory string. """ifself.working_directory.startswith("$PWD"):returnself.working_directory.replace("$PWD",os.getcwd(),1)elifself.working_directory.startswith("~"):returnself.working_directory.replace("~",os.path.expanduser("~"),1)else:returnself.working_directory
# --- Config structure: end. ---# Minimal observer-pattern like setup to trigger relevant changes when configure() is called.# To "subscribe":# from tempor.configuration import updated_on_configure# updated_on_configure.add(my_method)updated_on_configure:Set[Callable[[TemporConfig],None]]=set()# Register dataclass with Hydra config store for Hydra type checking._cs=hydra.core.config_store.ConfigStore.instance()_cs.store(name=tempor.import_name,node=TemporConfig)# Initialize OmegaConf schema._tempor_config_schema=OmegaConf.structured(TemporConfig)_this_module=sys.modules[__name__]# Needed to directly set `config` on this module in the configure() function.# pylint: disable=protected-access
[docs]defget_config()->TemporConfig:"""Get the current TemporAI configuration. Returns: TemporConfig: TemporAI configuration. """return_this_module._config
def_load(loaded_config:omegaconf.DictConfig)->TemporConfig:ifhasattr(_this_module,"_config"):merge_into=_this_module._configelse:merge_into=_tempor_config_schemamerged_validated_config=OmegaConf.merge(merge_into,loaded_config)config_as_dataclass=OmegaConf.to_container(merged_validated_config,structured_config_mode=omegaconf.SCMode.INSTANTIATE)ifTYPE_CHECKING:# pragma: no coverassertisinstance(config_as_dataclass,TemporConfig)# nosec B101returnconfig_as_dataclass
[docs]defload_yaml_file(path:Union[str,pathlib.Path])->TemporConfig:"""Load a YAML file as a `TemporConfig` object. Args: path (Union[str, pathlib.Path]): The path to the YAML file. Returns: TemporConfig: TemporAI configuration. """loaded=OmegaConf.load(path)ifTYPE_CHECKING:# pragma: no coverassertisinstance(loaded,omegaconf.DictConfig)# nosec B101return_load(loaded)
[docs]defload_dictconfig(config_node:omegaconf.DictConfig)->TemporConfig:"""Load an `omegaconf.DictConfig` as a `TemporConfig` object. Args: config_node (omegaconf.DictConfig): The configuration ``DictConfig``. Returns: TemporConfig: TemporAI configuration. """return_load(config_node)
[docs]defconfigure(new_config:Union[TemporConfig,omegaconf.DictConfig,str,pathlib.Path])->TemporConfig:"""Configure TemporAI with a new config. Args: new_config (Union[TemporConfig, omegaconf.DictConfig, str, pathlib.Path]): The new configuration. Can be a ``TemporConfig`` object, a ``DictConfig`` object, or a path to a YAML file. Returns: TemporConfig: TemporAI configuration. """ifisinstance(new_config,(str,pathlib.Path)):_this_module._config=load_yaml_file(path=new_config)# type: ignoreelifisinstance(new_config,omegaconf.DictConfig):_this_module._config=load_dictconfig(config_node=new_config)# type: ignoreelifisinstance(new_config,TemporConfig):_this_module._config=new_config# type: ignoreelse:raiseTypeError(f"`new_config` of type {type(new_config)} not supported")forupdaterinupdated_on_configure:updater(_this_module._config)return_this_module._config