From c434af9b92d68d08da87112ef424738e5e42ae6e Mon Sep 17 00:00:00 2001 From: wakonig_k Date: Tue, 15 Apr 2025 11:40:04 +0200 Subject: [PATCH] feat(plugin_utils): add functionality to retrieve auto update classes from plugins --- bec_widgets/utils/plugin_utils.py | 40 +++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/bec_widgets/utils/plugin_utils.py b/bec_widgets/utils/plugin_utils.py index ed0146eb..7b6d4f6a 100644 --- a/bec_widgets/utils/plugin_utils.py +++ b/bec_widgets/utils/plugin_utils.py @@ -1,7 +1,10 @@ +from __future__ import annotations + import importlib import inspect import os from dataclasses import dataclass +from typing import TYPE_CHECKING from bec_lib.plugin_helper import _get_available_plugins from qtpy.QtWidgets import QGraphicsWidget, QWidget @@ -9,6 +12,9 @@ from qtpy.QtWidgets import QGraphicsWidget, QWidget from bec_widgets.utils import BECConnector from bec_widgets.utils.bec_widget import BECWidget +if TYPE_CHECKING: # pragma: no cover + from bec_widgets.widgets.containers.auto_update.auto_updates import AutoUpdates + def get_plugin_widgets() -> dict[str, BECConnector]: """ @@ -45,6 +51,40 @@ def _filter_plugins(obj): return inspect.isclass(obj) and issubclass(obj, BECConnector) +def get_plugin_auto_updates() -> dict[str, type[AutoUpdates]]: + """ + Get all available auto update classes from the plugin directory. AutoUpdates must inherit from AutoUpdate and be + placed in the plugin repository's bec_widgets/auto_updates directory. The entry point for the auto updates is + specified in the respective pyproject.toml file using the following key: + [project.entry-points."bec.widgets.auto_updates"] + plugin_widgets_update = ".bec_widgets.auto_updates" + + e.g. + [project.entry-points."bec.widgets.auto_updates"] + plugin_widgets_update = "pxiii_bec.bec_widgets.auto_updates" + + Returns: + dict[str, AutoUpdates]: A dictionary of widget names and their respective classes. + """ + modules = _get_available_plugins("bec.widgets.auto_updates") + loaded_plugins = {} + for module in modules: + mods = inspect.getmembers(module, predicate=_filter_auto_updates) + for name, mod_cls in mods: + if name in loaded_plugins: + print(f"Duplicated auto update {name}.") + loaded_plugins[name] = mod_cls + return loaded_plugins + + +def _filter_auto_updates(obj): + from bec_widgets.widgets.containers.auto_update.auto_updates import AutoUpdates + + return ( + inspect.isclass(obj) and issubclass(obj, AutoUpdates) and not obj.__name__ == "AutoUpdates" + ) + + @dataclass class BECClassInfo: name: str