mirror of
https://github.com/bec-project/bec_widgets.git
synced 2025-07-13 19:21:50 +02:00
feat(bec_connector): export config to yaml
This commit is contained in:
@ -622,12 +622,6 @@ class BECFigure(RPCBase):
|
||||
list[BECPlotBase]: List of all widgets in the figure.
|
||||
"""
|
||||
|
||||
@rpc_call
|
||||
def apply_config(self, config: "dict | FigureConfig"):
|
||||
"""
|
||||
None
|
||||
"""
|
||||
|
||||
|
||||
class BECImageItem(RPCBase):
|
||||
@property
|
||||
|
@ -47,9 +47,6 @@ class JupyterConsoleWindow(QWidget): # pragma: no cover:
|
||||
"d0": self.d0,
|
||||
"d1": self.d1,
|
||||
"d2": self.d2,
|
||||
"fig0": self.fig0,
|
||||
"fig1": self.fig1,
|
||||
"fig2": self.fig2,
|
||||
"plt": self.plt,
|
||||
"bar": self.bar,
|
||||
}
|
||||
@ -108,6 +105,8 @@ class JupyterConsoleWindow(QWidget): # pragma: no cover:
|
||||
# curves for w1
|
||||
self.c1 = self.w1.get_config()
|
||||
|
||||
self.fig_c = self.figure.config_dict
|
||||
|
||||
def _init_dock(self):
|
||||
|
||||
self.d0 = self.dock.add_dock(name="dock_0")
|
||||
|
@ -1,15 +1,19 @@
|
||||
# pylint: disable = no-name-in-module,missing-module-docstring
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import time
|
||||
import uuid
|
||||
from typing import Optional
|
||||
|
||||
import yaml
|
||||
from bec_lib.utils.import_utils import lazy_import_from
|
||||
from pydantic import BaseModel, Field, field_validator
|
||||
from qtpy.QtCore import QObject, QRunnable, QThreadPool, Signal
|
||||
from qtpy.QtCore import Slot as pyqtSlot
|
||||
|
||||
from bec_widgets.cli.rpc_register import RPCRegister
|
||||
from bec_widgets.utils.yaml_dialog import load_yaml, load_yaml_gui, save_yaml, save_yaml_gui
|
||||
|
||||
BECDispatcher = lazy_import_from("bec_widgets.utils.bec_dispatcher", ("BECDispatcher",))
|
||||
|
||||
@ -161,6 +165,60 @@ class BECConnector:
|
||||
"""
|
||||
self.config = config
|
||||
|
||||
def apply_config(self, config: dict, generate_new_id: bool = True) -> None:
|
||||
"""
|
||||
Apply the configuration to the widget.
|
||||
|
||||
Args:
|
||||
config(dict): Configuration settings.
|
||||
generate_new_id(bool): If True, generate a new GUI ID for the widget.
|
||||
"""
|
||||
self.config = ConnectionConfig(**config)
|
||||
if generate_new_id is True:
|
||||
gui_id = str(uuid.uuid4())
|
||||
self.rpc_register.remove_rpc(self)
|
||||
self.set_gui_id(gui_id)
|
||||
self.rpc_register.add_rpc(self)
|
||||
else:
|
||||
self.gui_id = self.config.gui_id
|
||||
|
||||
def load_config(self, path: str | None = None, gui: bool = False):
|
||||
"""
|
||||
Load the configuration of the widget from YAML.
|
||||
|
||||
Args:
|
||||
path(str): Path to the configuration file for non-GUI dialog mode.
|
||||
gui(bool): If True, use the GUI dialog to load the configuration file.
|
||||
"""
|
||||
if gui is True:
|
||||
config = load_yaml_gui(self)
|
||||
else:
|
||||
config = load_yaml(path)
|
||||
|
||||
if config is not None:
|
||||
if config.get("widget_class") != self.__class__.__name__:
|
||||
raise ValueError(
|
||||
f"Configuration file is not for {self.__class__.__name__}. Got configuration for {config.get('widget_class')}."
|
||||
)
|
||||
self.apply_config(config)
|
||||
|
||||
def save_config(self, path: str | None = None, gui: bool = False):
|
||||
"""
|
||||
Save the configuration of the widget to YAML.
|
||||
|
||||
Args:
|
||||
path(str): Path to save the configuration file for non-GUI dialog mode.
|
||||
gui(bool): If True, use the GUI dialog to save the configuration file.
|
||||
"""
|
||||
if gui is True:
|
||||
save_yaml_gui(self, self.config_dict)
|
||||
else:
|
||||
if path is None:
|
||||
path = os.getcwd()
|
||||
file_path = os.path.join(path, f"{self.__class__.__name__}_config.yaml")
|
||||
|
||||
save_yaml(file_path, self.config_dict)
|
||||
|
||||
@pyqtSlot(str)
|
||||
def set_gui_id(self, gui_id: str) -> None:
|
||||
"""
|
||||
|
@ -6,7 +6,7 @@ import yaml
|
||||
from qtpy.QtWidgets import QFileDialog
|
||||
|
||||
|
||||
def load_yaml(instance) -> Union[dict, None]:
|
||||
def load_yaml_gui(instance) -> Union[dict, None]:
|
||||
"""
|
||||
Load YAML file from disk.
|
||||
|
||||
@ -20,12 +20,25 @@ def load_yaml(instance) -> Union[dict, None]:
|
||||
file_path, _ = QFileDialog.getOpenFileName(
|
||||
instance, "Load Settings", "", "YAML Files (*.yaml *.yml);;All Files (*)", options=options
|
||||
)
|
||||
config = load_yaml(file_path)
|
||||
return config
|
||||
|
||||
|
||||
def load_yaml(file_path: str) -> Union[dict, None]:
|
||||
"""
|
||||
Load YAML file from disk.
|
||||
|
||||
Args:
|
||||
file_path(str): Path to the YAML file.
|
||||
|
||||
Returns:
|
||||
dict: Configuration data loaded from the YAML file.
|
||||
"""
|
||||
if not file_path:
|
||||
return None
|
||||
try:
|
||||
with open(file_path, "r") as file:
|
||||
config = yaml.safe_load(file)
|
||||
config = yaml.load(file, Loader=yaml.FullLoader)
|
||||
return config
|
||||
|
||||
except FileNotFoundError:
|
||||
@ -38,7 +51,7 @@ def load_yaml(instance) -> Union[dict, None]:
|
||||
print(f"An error occurred while loading the settings from {file_path}: {e}")
|
||||
|
||||
|
||||
def save_yaml(instance, config: dict) -> None:
|
||||
def save_yaml_gui(instance, config: dict) -> None:
|
||||
"""
|
||||
Save YAML file to disk.
|
||||
|
||||
@ -51,6 +64,17 @@ def save_yaml(instance, config: dict) -> None:
|
||||
instance, "Save Settings", "", "YAML Files (*.yaml *.yml);;All Files (*)", options=options
|
||||
)
|
||||
|
||||
save_yaml(file_path, config)
|
||||
|
||||
|
||||
def save_yaml(file_path: str, config: dict) -> None:
|
||||
"""
|
||||
Save YAML file to disk.
|
||||
|
||||
Args:
|
||||
file_path(str): Path to the YAML file.
|
||||
config(dict): Configuration data to be saved.
|
||||
"""
|
||||
if not file_path:
|
||||
return
|
||||
try:
|
||||
|
@ -123,7 +123,9 @@ class BECFigure(BECConnector, pg.GraphicsLayoutWidget):
|
||||
"clear_all",
|
||||
"get_all_rpc",
|
||||
"widget_list",
|
||||
"apply_config",
|
||||
# "apply_config",
|
||||
# "save_config",
|
||||
# "load_config",
|
||||
]
|
||||
subplot_map = {
|
||||
"PlotBase": BECPlotBase,
|
||||
@ -173,7 +175,7 @@ class BECFigure(BECConnector, pg.GraphicsLayoutWidget):
|
||||
"Key must be a string (widget id) or a tuple of two integers (grid coordinates)"
|
||||
)
|
||||
|
||||
def apply_config(self, config: dict | FigureConfig):
|
||||
def apply_config(self, config: dict | FigureConfig): # ,generate_new_id: bool = False):
|
||||
if isinstance(config, dict):
|
||||
try:
|
||||
config = FigureConfig(**config)
|
||||
|
@ -7,7 +7,7 @@ import pytest
|
||||
import yaml
|
||||
from qtpy.QtWidgets import QPushButton, QVBoxLayout, QWidget
|
||||
|
||||
from bec_widgets.utils.yaml_dialog import load_yaml, save_yaml
|
||||
from bec_widgets.utils.yaml_dialog import load_yaml_gui, save_yaml_gui
|
||||
|
||||
|
||||
@pytest.fixture(scope="function")
|
||||
@ -33,7 +33,7 @@ def test_load_yaml(qtbot, example_widget):
|
||||
temp_file.write(b"name: test\nvalue: 42")
|
||||
|
||||
def load_yaml_wrapper():
|
||||
config = load_yaml(example_widget)
|
||||
config = load_yaml_gui(example_widget)
|
||||
if config:
|
||||
example_widget.config.update(config)
|
||||
|
||||
@ -49,7 +49,7 @@ def test_load_yaml(qtbot, example_widget):
|
||||
|
||||
def test_load_yaml_file_not_found(qtbot, example_widget, capsys):
|
||||
def load_yaml_wrapper():
|
||||
config = load_yaml(example_widget)
|
||||
config = load_yaml_gui(example_widget)
|
||||
if config:
|
||||
example_widget.config.update(config)
|
||||
|
||||
@ -76,7 +76,7 @@ def test_load_yaml_general_exception(qtbot, example_widget, capsys, monkeypatch)
|
||||
monkeypatch.setattr("builtins.open", mock_open)
|
||||
|
||||
def load_yaml_wrapper():
|
||||
config = load_yaml(example_widget)
|
||||
config = load_yaml_gui(example_widget)
|
||||
if config:
|
||||
example_widget.config.update(config)
|
||||
|
||||
@ -96,7 +96,7 @@ def test_load_yaml_permission_error(qtbot, example_widget, monkeypatch, capsys):
|
||||
os.chmod(temp_file_path, 0o000) # Remove permissions
|
||||
|
||||
def load_yaml_wrapper():
|
||||
config = load_yaml(example_widget)
|
||||
config = load_yaml_gui(example_widget)
|
||||
if config:
|
||||
example_widget.config.update(config)
|
||||
|
||||
@ -120,7 +120,7 @@ def test_load_yaml_invalid_yaml(qtbot, example_widget, capsys):
|
||||
temp_file.write(b"\tinvalid_yaml: [unbalanced_brackets: ]")
|
||||
|
||||
def load_yaml_wrapper():
|
||||
config = load_yaml(example_widget)
|
||||
config = load_yaml_gui(example_widget)
|
||||
if config:
|
||||
example_widget.config.update(config)
|
||||
|
||||
@ -147,7 +147,7 @@ def test_save_yaml(qtbot, example_widget):
|
||||
example_widget.saved_config = {"name": "test", "value": 42}
|
||||
|
||||
def save_yaml_wrapper():
|
||||
save_yaml(example_widget, example_widget.saved_config)
|
||||
save_yaml_gui(example_widget, example_widget.saved_config)
|
||||
|
||||
example_widget.export_button.clicked.connect(save_yaml_wrapper)
|
||||
|
||||
|
Reference in New Issue
Block a user