"""Module containing all function to import new plugins"""importimportlibfrompydanticimportBaseModel
[docs]classModuleImport(BaseModel):""" Data-Class to import a given python file from ``import_path`` and load the given ``class_name`` """import_path:strclass_name:str
[docs]defimport_class(self):"""Import the Module with class_name from the import path"""module=importlib.import_module(self.import_path)returngetattr(module,self.class_name)
[docs]classSaveUpdateDict(dict):""" Custom object to safely update the dictionary. Duplicate entries will raise an error. """
[docs]defupdate(self,new_dict,**kwargs)->None:"""Check if all modules have distinct identifier strings Args: new_dict: **kwargs: """duplicates=set(self.keys()).intersection(new_dict.keys())ifduplicates:raiseKeyError("One or multiple MODULE_TYPES contain ""the same string identifier (type). "f"The type has to be unique! {', '.join(duplicates)}")super().update(new_dict)
[docs]defload_plugin(name:str,loaded_classes:SaveUpdateDict,plugin_types_name:str):""" Loads the plugin based on the given name. Args: name str: Name of the plugin loaded_classes SaveUpdateDict: SaveUpdateDict instance with already loaded classes (modules or models) plugin_types_name str: Name of the dictionary in the plugin. Typical values are "MODULE_TYPES" or "MODEL_TYPES". """forkeyinloaded_classes:ifkey.startswith(f"{name}."):return# Already loadedtry:plugin=importlib.import_module(name)exceptImportErroraserr:raiseImportError(f"Plugin '{name}' is not installed.")fromerrtry:plugin_dict=getattr(plugin,plugin_types_name)exceptAttributeError:raiseImportError(f"Plugin '{name}' has no dictionary called "f"'{plugin_types_name}' to import plugin types.")ifnotisinstance(plugin_dict,dict):raiseTypeError(f"Loaded object '{plugin_types_name}' is not a dictionary "f"but a {type(plugin_dict)}")forkey,valueinplugin_dict.items():loaded_classes.update({f"{name}.{key}":value})