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 +6 -6
- PKG-INFO +1 -1
- bec_widgets/cli/client_utils.py +5 -2
- bec_widgets/cli/server.py +24 -10
- {bec_widgets-0.82.1.dist-info → bec_widgets-0.82.2.dist-info}/METADATA +1 -1
- {bec_widgets-0.82.1.dist-info → bec_widgets-0.82.2.dist-info}/RECORD +12 -11
- pyproject.toml +1 -1
- tests/unit_tests/test_client_utils.py +47 -0
- tests/unit_tests/test_rpc_server.py +42 -0
- {bec_widgets-0.82.1.dist-info → bec_widgets-0.82.2.dist-info}/WHEEL +0 -0
- {bec_widgets-0.82.1.dist-info → bec_widgets-0.82.2.dist-info}/entry_points.txt +0 -0
- {bec_widgets-0.82.1.dist-info → bec_widgets-0.82.2.dist-info}/licenses/LICENSE +0 -0
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
bec_widgets/cli/client_utils.py
CHANGED
@@ -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.
|
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
|
-
|
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)
|
@@ -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=
|
5
|
+
CHANGELOG.md,sha256=7VVqe14x1w6butWm_Du8rzXRFtf3RQYV3CsURU1-uT0,6428
|
6
6
|
LICENSE,sha256=YRKe85CBRyP7UpEAWwU8_qSIyuy5-l_9C-HKg5Qm8MQ,1511
|
7
|
-
PKG-INFO,sha256=
|
7
|
+
PKG-INFO,sha256=9lGCW5x2H2CEYe7DJsHs1LlXB0Pn_hr7efNeRFUGzgo,1309
|
8
8
|
README.md,sha256=Od69x-RS85Hph0-WwWACwal4yUd67XkEn4APEfHhHFw,2649
|
9
|
-
pyproject.toml,sha256=
|
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=
|
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=
|
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=
|
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.
|
246
|
-
bec_widgets-0.82.
|
247
|
-
bec_widgets-0.82.
|
248
|
-
bec_widgets-0.82.
|
249
|
-
bec_widgets-0.82.
|
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
@@ -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)
|
File without changes
|
File without changes
|
File without changes
|