From 4d74fe83671319e9ef899bfa680fa5c9d8aac13c Mon Sep 17 00:00:00 2001 From: graepaul_amdeng Date: Fri, 7 Aug 2026 09:45:09 -0700 Subject: [PATCH 1/2] Use copy to give system info to Tasks --- nodescraper/interfaces/dataplugin.py | 51 ++++++++++++++++++++-------- nodescraper/interfaces/plugin.py | 2 +- nodescraper/pluginexecutor.py | 2 +- 3 files changed, 39 insertions(+), 16 deletions(-) diff --git a/nodescraper/interfaces/dataplugin.py b/nodescraper/interfaces/dataplugin.py index 21d81b8e..1b34c899 100644 --- a/nodescraper/interfaces/dataplugin.py +++ b/nodescraper/interfaces/dataplugin.py @@ -65,7 +65,8 @@ class DataPlugin( - PluginInterface, Generic[TConnectionManager, TConnectArg, TDataModel, TCollectArg, TAnalyzeArg] + PluginInterface, + Generic[TConnectionManager, TConnectArg, TDataModel, TCollectArg, TAnalyzeArg], ): """Plugin used to collect and analyze data""" @@ -141,13 +142,17 @@ def _validate_collector_args(cls) -> None: return if isinstance(collector_args, dict): for collector_name, args_cls in collector_args.items(): - if not isinstance(args_cls, type) or not issubclass(args_cls, CollectorArgs): + if not isinstance(args_cls, type) or not issubclass( + args_cls, CollectorArgs + ): raise TypeError( f"COLLECTOR_ARGS[{collector_name!r}] must be a CollectorArgs subclass, " f"got {args_cls!r}" ) return - if not isinstance(collector_args, type) or not issubclass(collector_args, CollectorArgs): + if not isinstance(collector_args, type) or not issubclass( + collector_args, CollectorArgs + ): raise TypeError( f"COLLECTOR_ARGS must be a CollectorArgs subclass or dict, got {collector_args!r}" ) @@ -167,7 +172,9 @@ def _validate_class_var(cls): raise TypeError("CONNECTION_TYPE must be defined for collector") for collector_cls in cls.get_collector_classes(): - if not isinstance(collector_cls, type) or not issubclass(collector_cls, DataCollector): + if not isinstance(collector_cls, type) or not issubclass( + collector_cls, DataCollector + ): raise TypeError( f"COLLECTOR entries must be DataCollector subclasses, got {collector_cls!r}" ) @@ -278,13 +285,17 @@ def data(self, data: Optional[Union[str, dict, TDataModel]]): if isinstance(data, (str, dict)): self._data = self.DATA_MODEL.import_model(data) elif not isinstance(data, self.DATA_MODEL): - raise ValueError(f"data is invalid type, expected {self.DATA_MODEL.__class__.__name__}") + raise ValueError( + f"data is invalid type, expected {self.DATA_MODEL.__class__.__name__}" + ) else: self._data = data def collect( self, - max_event_priority_level: Optional[Union[EventPriority, str]] = EventPriority.CRITICAL, + max_event_priority_level: Optional[ + Union[EventPriority, str] + ] = EventPriority.CRITICAL, system_interaction_level: Optional[ Union[SystemInteractionLevel, str] ] = SystemInteractionLevel.INTERACTIVE, @@ -323,9 +334,11 @@ def collect( message=f"No connection manager type provided for {self.__class__.__name__}", ) return self.collection_result - self.logger.info("No connection manager provide, initializing connection manager") + self.logger.info( + "No connection manager provide, initializing connection manager" + ) self.connection_manager = self.CONNECTION_TYPE( - system_info=self.system_info, + system_info=self.system_info.model_copy(), logger=self.logger, parent=self.__class__.__name__, task_result_hooks=self.task_result_hooks, @@ -355,9 +368,11 @@ def collect( merged_data: Optional[TDataModel] = None for collector_cls in collector_classes: - collector_args = self._resolve_collector_args(collector_cls, collection_args) + collector_args = self._resolve_collector_args( + collector_cls, collection_args + ) collection_task = collector_cls( - system_info=self.system_info, + system_info=self.system_info.model_copy(), logger=self.logger, system_interaction_level=system_interaction_level, connection=self.connection_manager.connection, @@ -404,7 +419,9 @@ def collect( def analyze( self, - max_event_priority_level: Optional[Union[EventPriority, str]] = EventPriority.CRITICAL, + max_event_priority_level: Optional[ + Union[EventPriority, str] + ] = EventPriority.CRITICAL, analysis_args: Optional[Union[TAnalyzeArg, dict]] = None, data: Optional[Union[str, dict, TDataModel]] = None, ) -> TaskResult: @@ -448,7 +465,7 @@ def analyze( analysis_args = self.ANALYZER_ARGS.model_validate(analysis_args) analyzer_task = self.ANALYZER( - self.system_info, + system_info=self.system_info.model_copy(), logger=self.logger, max_event_priority_level=max_event_priority_level, parent=self.__class__.__name__, @@ -619,7 +636,9 @@ def load_datamodel_from_path(cls, dm_path: str) -> Optional[TDataModel]: import_model = getattr(data_model_cls, "import_model", None) if not callable(import_model): return None - base_import = getattr(DataModel.import_model, "__func__", DataModel.import_model) + base_import = getattr( + DataModel.import_model, "__func__", DataModel.import_model + ) if getattr(import_model, "__func__", import_model) is base_import: return None return import_model(dm_path) @@ -673,7 +692,11 @@ def load_run_data(cls, run_path: str) -> Optional[dict[str, Any]]: run_path = os.path.abspath(run_path) if not os.path.exists(run_path): return None - dm_path = run_path if os.path.isfile(run_path) else cls.find_datamodel_path_in_run(run_path) + dm_path = ( + run_path + if os.path.isfile(run_path) + else cls.find_datamodel_path_in_run(run_path) + ) if not dm_path: return None data_model = cls.load_datamodel_from_path(dm_path) diff --git a/nodescraper/interfaces/plugin.py b/nodescraper/interfaces/plugin.py index 9e22d346..9fe998d9 100644 --- a/nodescraper/interfaces/plugin.py +++ b/nodescraper/interfaces/plugin.py @@ -95,7 +95,7 @@ def __init__( if connection_args and self.CONNECTION_TYPE and not self.connection_manager: self.connection_manager = self.CONNECTION_TYPE( - system_info=self.system_info, + system_info=self.system_info.model_copy(), logger=logger, connection_args=connection_args, parent=self.__class__.__name__, diff --git a/nodescraper/pluginexecutor.py b/nodescraper/pluginexecutor.py index bb22b8a9..772f3662 100644 --- a/nodescraper/pluginexecutor.py +++ b/nodescraper/pluginexecutor.py @@ -111,7 +111,7 @@ def __init__( connection_manager = self.plugin_registry.connection_managers[connection] self.connection_library[connection_manager] = connection_manager( - system_info=self.system_info, + system_info=self.system_info.model_copy(), logger=self.logger, connection_args=connection_args, task_result_hooks=self.connection_result_hooks, From c1491751f2941d106b43e7a9ae4c1c1cdfd1d6e7 Mon Sep 17 00:00:00 2001 From: graepaul_amdeng Date: Fri, 7 Aug 2026 15:49:57 -0700 Subject: [PATCH 2/2] format --- nodescraper/interfaces/dataplugin.py | 42 +++++++--------------------- 1 file changed, 10 insertions(+), 32 deletions(-) diff --git a/nodescraper/interfaces/dataplugin.py b/nodescraper/interfaces/dataplugin.py index 1b34c899..1b18df28 100644 --- a/nodescraper/interfaces/dataplugin.py +++ b/nodescraper/interfaces/dataplugin.py @@ -142,17 +142,13 @@ def _validate_collector_args(cls) -> None: return if isinstance(collector_args, dict): for collector_name, args_cls in collector_args.items(): - if not isinstance(args_cls, type) or not issubclass( - args_cls, CollectorArgs - ): + if not isinstance(args_cls, type) or not issubclass(args_cls, CollectorArgs): raise TypeError( f"COLLECTOR_ARGS[{collector_name!r}] must be a CollectorArgs subclass, " f"got {args_cls!r}" ) return - if not isinstance(collector_args, type) or not issubclass( - collector_args, CollectorArgs - ): + if not isinstance(collector_args, type) or not issubclass(collector_args, CollectorArgs): raise TypeError( f"COLLECTOR_ARGS must be a CollectorArgs subclass or dict, got {collector_args!r}" ) @@ -172,9 +168,7 @@ def _validate_class_var(cls): raise TypeError("CONNECTION_TYPE must be defined for collector") for collector_cls in cls.get_collector_classes(): - if not isinstance(collector_cls, type) or not issubclass( - collector_cls, DataCollector - ): + if not isinstance(collector_cls, type) or not issubclass(collector_cls, DataCollector): raise TypeError( f"COLLECTOR entries must be DataCollector subclasses, got {collector_cls!r}" ) @@ -285,17 +279,13 @@ def data(self, data: Optional[Union[str, dict, TDataModel]]): if isinstance(data, (str, dict)): self._data = self.DATA_MODEL.import_model(data) elif not isinstance(data, self.DATA_MODEL): - raise ValueError( - f"data is invalid type, expected {self.DATA_MODEL.__class__.__name__}" - ) + raise ValueError(f"data is invalid type, expected {self.DATA_MODEL.__class__.__name__}") else: self._data = data def collect( self, - max_event_priority_level: Optional[ - Union[EventPriority, str] - ] = EventPriority.CRITICAL, + max_event_priority_level: Optional[Union[EventPriority, str]] = EventPriority.CRITICAL, system_interaction_level: Optional[ Union[SystemInteractionLevel, str] ] = SystemInteractionLevel.INTERACTIVE, @@ -334,9 +324,7 @@ def collect( message=f"No connection manager type provided for {self.__class__.__name__}", ) return self.collection_result - self.logger.info( - "No connection manager provide, initializing connection manager" - ) + self.logger.info("No connection manager provide, initializing connection manager") self.connection_manager = self.CONNECTION_TYPE( system_info=self.system_info.model_copy(), logger=self.logger, @@ -368,9 +356,7 @@ def collect( merged_data: Optional[TDataModel] = None for collector_cls in collector_classes: - collector_args = self._resolve_collector_args( - collector_cls, collection_args - ) + collector_args = self._resolve_collector_args(collector_cls, collection_args) collection_task = collector_cls( system_info=self.system_info.model_copy(), logger=self.logger, @@ -419,9 +405,7 @@ def collect( def analyze( self, - max_event_priority_level: Optional[ - Union[EventPriority, str] - ] = EventPriority.CRITICAL, + max_event_priority_level: Optional[Union[EventPriority, str]] = EventPriority.CRITICAL, analysis_args: Optional[Union[TAnalyzeArg, dict]] = None, data: Optional[Union[str, dict, TDataModel]] = None, ) -> TaskResult: @@ -636,9 +620,7 @@ def load_datamodel_from_path(cls, dm_path: str) -> Optional[TDataModel]: import_model = getattr(data_model_cls, "import_model", None) if not callable(import_model): return None - base_import = getattr( - DataModel.import_model, "__func__", DataModel.import_model - ) + base_import = getattr(DataModel.import_model, "__func__", DataModel.import_model) if getattr(import_model, "__func__", import_model) is base_import: return None return import_model(dm_path) @@ -692,11 +674,7 @@ def load_run_data(cls, run_path: str) -> Optional[dict[str, Any]]: run_path = os.path.abspath(run_path) if not os.path.exists(run_path): return None - dm_path = ( - run_path - if os.path.isfile(run_path) - else cls.find_datamodel_path_in_run(run_path) - ) + dm_path = run_path if os.path.isfile(run_path) else cls.find_datamodel_path_in_run(run_path) if not dm_path: return None data_model = cls.load_datamodel_from_path(dm_path)