bec-widgets 0.82.1__py3-none-any.whl → 0.82.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## v0.82.2 (2024-07-08)
4
+
5
+ ### Fix
6
+
7
+ * fix(rpc_server): pass cli config to server ([`90178e2`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/90178e2f61fa9dac7d82c0d0db40a9767bb133e6))
8
+
3
9
  ## v0.82.1 (2024-07-07)
4
10
 
5
11
  ### Fix
@@ -132,10 +138,6 @@
132
138
 
133
139
  ## v0.77.0 (2024-07-02)
134
140
 
135
- ### Feature
136
-
137
- * feat(bec_connector): export config to yaml ([`a391f30`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/a391f3018c50fee6a4a06884491b957df80c3cd3))
138
-
139
141
  ### Fix
140
142
 
141
143
  * fix(waveform): scatter 2D brush error ([`215d59c`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/215d59c8bfe7fda9aff8cec8353bef9e1ce2eca1))
@@ -143,5 +145,3 @@
143
145
  * fix(figure): API cleanup ([`008a33a`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/008a33a9b192473cc58e90cd6d98c5bcb5f7b8c0))
144
146
 
145
147
  * fix(figure): if/else logic corrected in subplot_factory ([`3e78723`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/3e787234c7274b0698423d7bf9a4c54ec46bad5f))
146
-
147
- * fix(image): processing of already displayed data; closes #106 ([`1173510`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/1173510105d2d70d7e498c2ac1e122cea3a16597))
PKG-INFO CHANGED
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: bec_widgets
3
- Version: 0.82.1
3
+ Version: 0.82.2
4
4
  Summary: BEC Widgets
5
5
  Project-URL: Bug Tracker, https://gitlab.psi.ch/bec/bec_widgets/issues
6
6
  Project-URL: Homepage, https://gitlab.psi.ch/bec/bec_widgets
@@ -2,6 +2,7 @@ from __future__ import annotations
2
2
 
3
3
  import importlib
4
4
  import importlib.metadata as imd
5
+ import json
5
6
  import os
6
7
  import select
7
8
  import subprocess
@@ -87,7 +88,7 @@ def _get_output(process, logger) -> None:
87
88
  print(f"Error reading process output: {str(e)}")
88
89
 
89
90
 
90
- def _start_plot_process(gui_id, gui_class, config, logger=None) -> None:
91
+ def _start_plot_process(gui_id: str, gui_class: type, config: dict | str, logger=None) -> None:
91
92
  """
92
93
  Start the plot in a new process.
93
94
 
@@ -98,6 +99,8 @@ def _start_plot_process(gui_id, gui_class, config, logger=None) -> None:
98
99
  # pylint: disable=subprocess-run-check
99
100
  command = ["bec-gui-server", "--id", gui_id, "--gui_class", gui_class.__name__]
100
101
  if config:
102
+ if isinstance(config, dict):
103
+ config = json.dumps(config)
101
104
  command.extend(["--config", config])
102
105
 
103
106
  env_dict = os.environ.copy()
@@ -190,7 +193,7 @@ class BECGuiClientMixin:
190
193
  if self._process is None or self._process.poll() is not None:
191
194
  self._start_update_script()
192
195
  self._process, self._process_output_processing_thread = _start_plot_process(
193
- self._gui_id, self.__class__, self._client._service_config.config_path
196
+ self._gui_id, self.__class__, self._client._service_config.config
194
197
  )
195
198
  while not self.gui_is_alive():
196
199
  print("Waiting for GUI to start...")
bec_widgets/cli/server.py CHANGED
@@ -1,6 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import inspect
4
+ import json
4
5
  import signal
5
6
  import sys
6
7
  from contextlib import redirect_stderr, redirect_stdout
@@ -141,10 +142,30 @@ class SimpleFileLikeFromLogOutputFunc:
141
142
  return
142
143
 
143
144
 
145
+ def _start_server(gui_id: str, gui_class: Union[BECFigure, BECDockArea], config: str | None = None):
146
+ if config:
147
+ try:
148
+ config = json.loads(config)
149
+ service_config = ServiceConfig(config=config)
150
+ except (json.JSONDecodeError, TypeError):
151
+ service_config = ServiceConfig(config_path=config)
152
+ else:
153
+ # if no config is provided, use the default config
154
+ service_config = ServiceConfig()
155
+
156
+ bec_logger.configure(
157
+ service_config.redis,
158
+ QtRedisConnector,
159
+ service_name="BECWidgetsCLIServer",
160
+ service_config=service_config.service_config,
161
+ )
162
+ server = BECWidgetsCLIServer(gui_id=gui_id, config=service_config, gui_class=gui_class)
163
+ return server
164
+
165
+
144
166
  def main():
145
167
  import argparse
146
168
  import os
147
- import sys
148
169
 
149
170
  from qtpy.QtCore import QSize
150
171
  from qtpy.QtGui import QIcon
@@ -159,7 +180,7 @@ def main():
159
180
  type=str,
160
181
  help="Name of the gui class to be rendered. Possible values: \n- BECFigure\n- BECDockArea",
161
182
  )
162
- parser.add_argument("--config", type=str, help="Config file")
183
+ parser.add_argument("--config", type=str, help="Config file or config string.")
163
184
 
164
185
  args = parser.parse_args()
165
186
 
@@ -188,14 +209,7 @@ def main():
188
209
  win = QMainWindow()
189
210
  win.setWindowTitle("BEC Widgets")
190
211
 
191
- service_config = ServiceConfig(args.config)
192
- bec_logger.configure(
193
- service_config.redis,
194
- QtRedisConnector,
195
- service_name="BECWidgetsCLIServer",
196
- service_config=service_config.service_config,
197
- )
198
- server = BECWidgetsCLIServer(gui_id=args.id, config=service_config, gui_class=gui_class)
212
+ server = _start_server(args.id, gui_class, args.config)
199
213
 
200
214
  gui = server.gui
201
215
  win.setCentralWidget(gui)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: bec_widgets
3
- Version: 0.82.1
3
+ Version: 0.82.2
4
4
  Summary: BEC Widgets
5
5
  Project-URL: Bug Tracker, https://gitlab.psi.ch/bec/bec_widgets/issues
6
6
  Project-URL: Homepage, https://gitlab.psi.ch/bec/bec_widgets
@@ -2,11 +2,11 @@
2
2
  .gitlab-ci.yml,sha256=vuDJPAYOK0995_H6fu0N5dIgIrOJgTvKr0HZkNWlxMw,8142
3
3
  .pylintrc,sha256=eeY8YwSI74oFfq6IYIbCqnx3Vk8ZncKaatv96n_Y8Rs,18544
4
4
  .readthedocs.yaml,sha256=aSOc277LqXcsTI6lgvm_JY80lMlr69GbPKgivua2cS0,603
5
- CHANGELOG.md,sha256=51OXCmE8Hehc5TNpYDvNRXUi5tTewjqPN-MzOIpdoFY,6575
5
+ CHANGELOG.md,sha256=7VVqe14x1w6butWm_Du8rzXRFtf3RQYV3CsURU1-uT0,6428
6
6
  LICENSE,sha256=YRKe85CBRyP7UpEAWwU8_qSIyuy5-l_9C-HKg5Qm8MQ,1511
7
- PKG-INFO,sha256=HDswJisHfyksMUD6G3xvmym8cQlpX85Mf6i16-m6jKM,1309
7
+ PKG-INFO,sha256=9lGCW5x2H2CEYe7DJsHs1LlXB0Pn_hr7efNeRFUGzgo,1309
8
8
  README.md,sha256=Od69x-RS85Hph0-WwWACwal4yUd67XkEn4APEfHhHFw,2649
9
- pyproject.toml,sha256=BzRmQleEbvlRpmEbGMq6GfGWaVHIQMQxoqypM_B_yZ8,2358
9
+ pyproject.toml,sha256=Jsa50E-GnKAaTBdJplPyg-B7sHQsIPL2GS-IHwugDFA,2358
10
10
  .git_hooks/pre-commit,sha256=n3RofIZHJl8zfJJIUomcMyYGFi_rwq4CC19z0snz3FI,286
11
11
  .gitlab/issue_templates/bug_report_template.md,sha256=gAuyEwl7XlnebBrkiJ9AqffSNOywmr8vygUFWKTuQeI,386
12
12
  .gitlab/issue_templates/documentation_update_template.md,sha256=FHLdb3TS_D9aL4CYZCjyXSulbaW5mrN2CmwTaeLPbNw,860
@@ -18,11 +18,11 @@ bec_widgets/assets/terminal_icon.png,sha256=bJl7Tft4Fi2uxvuXI8o14uMHnI9eAWKSU2uf
18
18
  bec_widgets/cli/__init__.py,sha256=d0Q6Fn44e7wFfLabDOBxpcJ1DPKWlFunGYDUBmO-4hA,22
19
19
  bec_widgets/cli/auto_updates.py,sha256=DyBV3HnjMSH-cvVkYNcDiYKVf0Xut4Qy2qGQqkW47Bw,4833
20
20
  bec_widgets/cli/client.py,sha256=MMDy1edr1j9klgVGZZmD1dzLxi74gp75Jf4FNed9al8,60084
21
- bec_widgets/cli/client_utils.py,sha256=zq1gPW7t4n9Nsn4MLkdUeKwwl-9nUcf5UjuN8lZr9iY,12281
21
+ bec_widgets/cli/client_utils.py,sha256=cDhabblwaP88a0jlVpbn_RWWKVbsyjhmmGtMh9gesEw,12388
22
22
  bec_widgets/cli/generate_cli.py,sha256=Ea5px9KblUlcGg-1JbJBTIU7laGg2n8PM7Efw9WVVzM,5889
23
23
  bec_widgets/cli/rpc_register.py,sha256=QxXUZu5XNg00Yf5O3UHWOXg3-f_pzKjjoZYMOa-MOJc,2216
24
24
  bec_widgets/cli/rpc_wigdet_handler.py,sha256=6kQng2DyS6rhLJqSJ7xa0kdgSxp-35A2upcf833dJRE,1483
25
- bec_widgets/cli/server.py,sha256=2EJvkQDzrDTsZjRPs7g2v_iPTspGqxzY34tRAnvjxjY,7281
25
+ bec_widgets/cli/server.py,sha256=FZkqsjUHIkCUFMKUFm7ls_eslXvhIFzLpINEYxeWP5s,7722
26
26
  bec_widgets/examples/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
27
27
  bec_widgets/examples/jupyter_console/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
28
28
  bec_widgets/examples/jupyter_console/jupyter_console_window.py,sha256=oOVCTY68bAn9HDFd5W_xNqQhI7Nsm7TaqYYLqLWXo2w,5520
@@ -213,7 +213,7 @@ tests/unit_tests/test_bec_image.py,sha256=mjvcrHgOF_FCj6WbUyxvZH9HL63QGA5C0PNZ5d
213
213
  tests/unit_tests/test_bec_motor_map.py,sha256=dSYopbZS8lGD9cB26Kwmqw5zBoKCZs8t7DEEr50ug-g,8532
214
214
  tests/unit_tests/test_bec_queue.py,sha256=u-uc-iZeGAS8P90o6Cxy5oz_60zHpirGAu04OgQPDXw,4598
215
215
  tests/unit_tests/test_bec_status_box.py,sha256=gZdjyy9DNuUP9UwleTLj2Dp5HUImiqnkHjXWiqL0Q-o,4868
216
- tests/unit_tests/test_client_utils.py,sha256=eViJ1Tz-HX9TkMvQH6W8cO-c3_1I8bUc4_Yen6LOc0E,830
216
+ tests/unit_tests/test_client_utils.py,sha256=CBdWIVJ_UiyFzTJnX3XJm4PGw2uXhFvRCP_Y9ifckbw,2630
217
217
  tests/unit_tests/test_color_validation.py,sha256=xbFbtFDia36XLgaNrX2IwvAX3IDC_Odpj5BGoJSgiIE,2389
218
218
  tests/unit_tests/test_crosshair.py,sha256=3OMAJ2ZaISYXMOtkXf1rPdy94vCr8njeLi6uHblBL9Q,5045
219
219
  tests/unit_tests/test_device_input_base.py,sha256=r1tI7BFAhpv7V7gf_n5gjusyrBFOfuCqIkdVg7YA7vY,2444
@@ -225,6 +225,7 @@ tests/unit_tests/test_plot_base.py,sha256=vWbt-QO5blSoE5C1392MIFha9A9JnUsx_D_9yT
225
225
  tests/unit_tests/test_plugin_utils.py,sha256=ayksWdrFY7kOiA0wVEjKFmFCF3UhH3lG8tzPVOpwysk,528
226
226
  tests/unit_tests/test_ring_progress_bar.py,sha256=hDlqkQho7FR7HAfM4Zrr4q1m773a3_rQ8CbM1GqDDSE,12252
227
227
  tests/unit_tests/test_rpc_register.py,sha256=hECjZEimd440mwRrO0rg7L3PKN7__3DgjmESN6wx3bo,1179
228
+ tests/unit_tests/test_rpc_server.py,sha256=MvstcvqUsnGAzUxw8Et1xXXikk_VIxFPwDZD0v1QGkg,1500
228
229
  tests/unit_tests/test_rpc_widget_handler.py,sha256=ceQ3BPnBIFY2Hy-sDPw0wxxREVTTphILts0gvX9qoUw,234
229
230
  tests/unit_tests/test_scan_control.py,sha256=Wr6KcE8av4sEIOx5VgYbzVCem3Jgb4Kzx_oOuvwlmkE,13459
230
231
  tests/unit_tests/test_scan_control_group_box.py,sha256=HNqjP10B_NonikspNwKz9upJU-t7xf6hwBerNhbC-uo,5563
@@ -242,8 +243,8 @@ tests/unit_tests/test_configs/config_device_no_entry.yaml,sha256=hdvue9KLc_kfNzG
242
243
  tests/unit_tests/test_configs/config_scan.yaml,sha256=vo484BbWOjA_e-h6bTjSV9k7QaQHrlAvx-z8wtY-P4E,1915
243
244
  tests/unit_tests/test_msgs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
244
245
  tests/unit_tests/test_msgs/available_scans_message.py,sha256=m_z97hIrjHXXMa2Ex-UvsPmTxOYXfjxyJaGkIY6StTY,46532
245
- bec_widgets-0.82.1.dist-info/METADATA,sha256=HDswJisHfyksMUD6G3xvmym8cQlpX85Mf6i16-m6jKM,1309
246
- bec_widgets-0.82.1.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
247
- bec_widgets-0.82.1.dist-info/entry_points.txt,sha256=3otEkCdDB9LZJuBLzG4pFLK5Di0CVybN_12IsZrQ-58,166
248
- bec_widgets-0.82.1.dist-info/licenses/LICENSE,sha256=YRKe85CBRyP7UpEAWwU8_qSIyuy5-l_9C-HKg5Qm8MQ,1511
249
- bec_widgets-0.82.1.dist-info/RECORD,,
246
+ bec_widgets-0.82.2.dist-info/METADATA,sha256=9lGCW5x2H2CEYe7DJsHs1LlXB0Pn_hr7efNeRFUGzgo,1309
247
+ bec_widgets-0.82.2.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
248
+ bec_widgets-0.82.2.dist-info/entry_points.txt,sha256=3otEkCdDB9LZJuBLzG4pFLK5Di0CVybN_12IsZrQ-58,166
249
+ bec_widgets-0.82.2.dist-info/licenses/LICENSE,sha256=YRKe85CBRyP7UpEAWwU8_qSIyuy5-l_9C-HKg5Qm8MQ,1511
250
+ bec_widgets-0.82.2.dist-info/RECORD,,
pyproject.toml CHANGED
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "bec_widgets"
7
- version = "0.82.1"
7
+ version = "0.82.2"
8
8
  description = "BEC Widgets"
9
9
  requires-python = ">=3.10"
10
10
  classifiers = [
@@ -3,6 +3,7 @@ from unittest import mock
3
3
  import pytest
4
4
 
5
5
  from bec_widgets.cli.client import BECFigure
6
+ from bec_widgets.cli.client_utils import BECGuiClientMixin, _start_plot_process
6
7
 
7
8
  from .client_mocks import FakeDevice
8
9
 
@@ -27,3 +28,49 @@ def test_rpc_call_accepts_device_as_input(cli_figure):
27
28
  fig, mock_rpc_call = cli_figure
28
29
  fig.plot(x_name=dev1, y_name=dev2)
29
30
  mock_rpc_call.assert_called_with("plot", x_name="samx", y_name="bpm4i")
31
+
32
+
33
+ @pytest.mark.parametrize(
34
+ "config, call_config",
35
+ [
36
+ (None, None),
37
+ ("/path/to/config.yml", "/path/to/config.yml"),
38
+ ({"key": "value"}, '{"key": "value"}'),
39
+ ],
40
+ )
41
+ def test_client_utils_start_plot_process(config, call_config):
42
+ with mock.patch("bec_widgets.cli.client_utils.subprocess.Popen") as mock_popen:
43
+ _start_plot_process("gui_id", BECFigure, config)
44
+ command = ["bec-gui-server", "--id", "gui_id", "--gui_class", "BECFigure"]
45
+ if call_config:
46
+ command.extend(["--config", call_config])
47
+ mock_popen.assert_called_once_with(
48
+ command,
49
+ text=True,
50
+ start_new_session=True,
51
+ stdout=mock.ANY,
52
+ stderr=mock.ANY,
53
+ env=mock.ANY,
54
+ )
55
+
56
+
57
+ def test_client_utils_passes_client_config_to_server(bec_dispatcher):
58
+ """
59
+ Test that the client config is passed to the server. This ensures that
60
+ changes to the client config (either through config files or plugins) are
61
+ reflected in the server.
62
+ """
63
+ mixin = BECGuiClientMixin()
64
+ mixin._client = bec_dispatcher.client
65
+ mixin._gui_id = "gui_id"
66
+ mixin.gui_is_alive = mock.MagicMock()
67
+ mixin.gui_is_alive.side_effect = [True]
68
+
69
+ with mock.patch("bec_widgets.cli.client_utils._start_plot_process") as mock_start_plot:
70
+ with mock.patch.object(mixin, "_start_update_script") as mock_start_update:
71
+ mock_start_plot.return_value = [mock.MagicMock(), mock.MagicMock()]
72
+ mixin.show()
73
+ mock_start_plot.assert_called_once_with(
74
+ "gui_id", BECGuiClientMixin, mixin._client._service_config.config
75
+ )
76
+ mock_start_update.assert_called_once()
@@ -0,0 +1,42 @@
1
+ from unittest import mock
2
+
3
+ import pytest
4
+ from bec_lib.service_config import ServiceConfig
5
+
6
+ from bec_widgets.cli.server import _start_server
7
+ from bec_widgets.widgets.figure import BECFigure
8
+
9
+
10
+ @pytest.fixture
11
+ def mocked_cli_server():
12
+ with mock.patch("bec_widgets.cli.server.BECWidgetsCLIServer") as mock_server:
13
+ with mock.patch("bec_widgets.cli.server.ServiceConfig") as mock_config:
14
+ with mock.patch("bec_lib.logger.bec_logger.configure") as mock_logger:
15
+ yield mock_server, mock_config, mock_logger
16
+
17
+
18
+ def test_rpc_server_start_server_without_service_config(mocked_cli_server):
19
+ """
20
+ Test that the server is started with the correct arguments.
21
+ """
22
+ mock_server, mock_config, _ = mocked_cli_server
23
+
24
+ _start_server("gui_id", BECFigure, None)
25
+ mock_server.assert_called_once_with(gui_id="gui_id", config=mock_config(), gui_class=BECFigure)
26
+
27
+
28
+ @pytest.mark.parametrize(
29
+ "config, call_config",
30
+ [
31
+ ("/path/to/config.yml", {"config_path": "/path/to/config.yml"}),
32
+ ({"key": "value"}, {"config": {"key": "value"}}),
33
+ ],
34
+ )
35
+ def test_rpc_server_start_server_with_service_config(mocked_cli_server, config, call_config):
36
+ """
37
+ Test that the server is started with the correct arguments.
38
+ """
39
+ mock_server, mock_config, _ = mocked_cli_server
40
+ config = mock_config(**call_config)
41
+ _start_server("gui_id", BECFigure, config)
42
+ mock_server.assert_called_once_with(gui_id="gui_id", config=config, gui_class=BECFigure)