diff --git a/bec_widgets/cli/client.py b/bec_widgets/cli/client.py index 49ee5592..7ce1f92d 100644 --- a/bec_widgets/cli/client.py +++ b/bec_widgets/cli/client.py @@ -5,6 +5,7 @@ from __future__ import annotations import enum import inspect +import traceback from typing import Literal, Optional from bec_lib.logger import bec_logger @@ -47,29 +48,32 @@ _Widgets = { } -_plugin_widgets = get_all_plugin_widgets() -plugin_client = get_plugin_client_module() -Widgets = _WidgetsEnumType("Widgets", {name: name for name in _plugin_widgets} | _Widgets) +try: + _plugin_widgets = get_all_plugin_widgets() + plugin_client = get_plugin_client_module() + Widgets = _WidgetsEnumType("Widgets", {name: name for name in _plugin_widgets} | _Widgets) -if (_overlap := _Widgets.keys() & _plugin_widgets.keys()) != set(): - for _widget in _overlap: - logger.warning( - f"Detected duplicate widget {_widget} in plugin repo file: {inspect.getfile(_plugin_widgets[_widget])} !" - ) -for plugin_name, plugin_class in inspect.getmembers(plugin_client, inspect.isclass): - if issubclass(plugin_class, RPCBase) and plugin_class is not RPCBase: - if plugin_name in globals(): - conflicting_file = ( - inspect.getfile(_plugin_widgets[plugin_name]) - if plugin_name in _plugin_widgets - else f"{plugin_client}" - ) + if (_overlap := _Widgets.keys() & _plugin_widgets.keys()) != set(): + for _widget in _overlap: logger.warning( - f"Plugin widget {plugin_name} from {conflicting_file} conflicts with a built-in class!" + f"Detected duplicate widget {_widget} in plugin repo file: {inspect.getfile(_plugin_widgets[_widget])} !" ) - continue - if plugin_name not in _overlap: - globals()[plugin_name] = plugin_class + for plugin_name, plugin_class in inspect.getmembers(plugin_client, inspect.isclass): + if issubclass(plugin_class, RPCBase) and plugin_class is not RPCBase: + if plugin_name in globals(): + conflicting_file = ( + inspect.getfile(_plugin_widgets[plugin_name]) + if plugin_name in _plugin_widgets + else f"{plugin_client}" + ) + logger.warning( + f"Plugin widget {plugin_name} from {conflicting_file} conflicts with a built-in class!" + ) + continue + if plugin_name not in _overlap: + globals()[plugin_name] = plugin_class +except ImportError as e: + logger.error(f"Failed loading plugins: \n{reduce(add, traceback.format_exception(e))}") class AutoUpdates(RPCBase): diff --git a/bec_widgets/cli/generate_cli.py b/bec_widgets/cli/generate_cli.py index 1ab06bd5..7b85a38c 100644 --- a/bec_widgets/cli/generate_cli.py +++ b/bec_widgets/cli/generate_cli.py @@ -39,6 +39,7 @@ class ClientGenerator: base_imports = ( """import enum import inspect +import traceback from typing import Literal, Optional """ if self._base @@ -107,28 +108,30 @@ _Widgets = { if self._base: self.content += """ -_plugin_widgets = get_all_plugin_widgets() -plugin_client = get_plugin_client_module() -Widgets = _WidgetsEnumType("Widgets", {name: name for name in _plugin_widgets} | _Widgets) - -if (_overlap := _Widgets.keys() & _plugin_widgets.keys()) != set(): - for _widget in _overlap: - logger.warning(f"Detected duplicate widget {_widget} in plugin repo file: {inspect.getfile(_plugin_widgets[_widget])} !") -for plugin_name, plugin_class in inspect.getmembers(plugin_client, inspect.isclass): - if issubclass(plugin_class, RPCBase) and plugin_class is not RPCBase: - if plugin_name in globals(): - conflicting_file = ( - inspect.getfile(_plugin_widgets[plugin_name]) - if plugin_name in _plugin_widgets - else f"{plugin_client}" - ) - logger.warning( - f"Plugin widget {plugin_name} from {conflicting_file} conflicts with a built-in class!" - ) - continue - if plugin_name not in _overlap: - globals()[plugin_name] = plugin_class +try: + _plugin_widgets = get_all_plugin_widgets() + plugin_client = get_plugin_client_module() + Widgets = _WidgetsEnumType("Widgets", {name: name for name in _plugin_widgets} | _Widgets) + if (_overlap := _Widgets.keys() & _plugin_widgets.keys()) != set(): + for _widget in _overlap: + logger.warning(f"Detected duplicate widget {_widget} in plugin repo file: {inspect.getfile(_plugin_widgets[_widget])} !") + for plugin_name, plugin_class in inspect.getmembers(plugin_client, inspect.isclass): + if issubclass(plugin_class, RPCBase) and plugin_class is not RPCBase: + if plugin_name in globals(): + conflicting_file = ( + inspect.getfile(_plugin_widgets[plugin_name]) + if plugin_name in _plugin_widgets + else f"{plugin_client}" + ) + logger.warning( + f"Plugin widget {plugin_name} from {conflicting_file} conflicts with a built-in class!" + ) + continue + if plugin_name not in _overlap: + globals()[plugin_name] = plugin_class +except ImportError as e: + logger.error(f"Failed loading plugins: \\n{reduce(add, traceback.format_exception(e))}") """ def generate_content_for_class(self, cls): diff --git a/tests/unit_tests/test_generate_cli_client.py b/tests/unit_tests/test_generate_cli_client.py index ade379cb..2f76ea3a 100644 --- a/tests/unit_tests/test_generate_cli_client.py +++ b/tests/unit_tests/test_generate_cli_client.py @@ -72,6 +72,7 @@ def test_client_generator_with_black_formatting(): import enum import inspect + import traceback from typing import Literal, Optional from bec_lib.logger import bec_logger @@ -95,27 +96,30 @@ def test_client_generator_with_black_formatting(): } - _plugin_widgets = get_all_plugin_widgets() - plugin_client = get_plugin_client_module() - Widgets = _WidgetsEnumType("Widgets", {name: name for name in _plugin_widgets} | _Widgets) + try: + _plugin_widgets = get_all_plugin_widgets() + plugin_client = get_plugin_client_module() + Widgets = _WidgetsEnumType("Widgets", {name: name for name in _plugin_widgets} | _Widgets) - if (_overlap := _Widgets.keys() & _plugin_widgets.keys()) != set(): - for _widget in _overlap: - logger.warning(f"Detected duplicate widget {_widget} in plugin repo file: {inspect.getfile(_plugin_widgets[_widget])} !") - for plugin_name, plugin_class in inspect.getmembers(plugin_client, inspect.isclass): - if issubclass(plugin_class, RPCBase) and plugin_class is not RPCBase: - if plugin_name in globals(): - conflicting_file = ( - inspect.getfile(_plugin_widgets[plugin_name]) - if plugin_name in _plugin_widgets - else f"{plugin_client}" - ) - logger.warning( - f"Plugin widget {plugin_name} from {conflicting_file} conflicts with a built-in class!" - ) - continue - if plugin_name not in _overlap: - globals()[plugin_name] = plugin_class + if (_overlap := _Widgets.keys() & _plugin_widgets.keys()) != set(): + for _widget in _overlap: + logger.warning(f"Detected duplicate widget {_widget} in plugin repo file: {inspect.getfile(_plugin_widgets[_widget])} !") + for plugin_name, plugin_class in inspect.getmembers(plugin_client, inspect.isclass): + if issubclass(plugin_class, RPCBase) and plugin_class is not RPCBase: + if plugin_name in globals(): + conflicting_file = ( + inspect.getfile(_plugin_widgets[plugin_name]) + if plugin_name in _plugin_widgets + else f"{plugin_client}" + ) + logger.warning( + f"Plugin widget {plugin_name} from {conflicting_file} conflicts with a built-in class!" + ) + continue + if plugin_name not in _overlap: + globals()[plugin_name] = plugin_class + except ImportError as e: + logger.error(f"Failed loading plugins: \\n{reduce(add, traceback.format_exception(e))}") class MockBECFigure(RPCBase): @rpc_call