bec-widgets 2.1.1__py3-none-any.whl → 2.1.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.
.gitlab-ci.yml CHANGED
@@ -230,7 +230,7 @@ end-2-end-conda:
230
230
  - pip install -e ./ophyd_devices
231
231
 
232
232
  - pip install -e .[dev,pyside6]
233
- - pytest -v --files-path ./ --start-servers --flush-redis --random-order ./tests/end-2-end
233
+ - pytest -v --files-path ./ --start-servers --random-order ./tests/end-2-end
234
234
 
235
235
  artifacts:
236
236
  when: on_failure
CHANGELOG.md CHANGED
@@ -1,6 +1,28 @@
1
1
  # CHANGELOG
2
2
 
3
3
 
4
+ ## v2.1.2 (2025-05-06)
5
+
6
+ ### Bug Fixes
7
+
8
+ - **waveform**: Ignore callbacks for on_async_readback from QtSender objects that are already
9
+ destroyed; closes #497
10
+ ([`64a4824`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/64a48240546846fdf4541c2adf3a0a5a0829f948))
11
+
12
+ ### Build System
13
+
14
+ - Remove flush-redis from ci job
15
+ ([`a6c479e`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/a6c479e42ea2a47c45e5a323bb3072bab503ecf1))
16
+
17
+ ### Refactoring
18
+
19
+ - **bec-progressbar**: Add private method for bec_progressbar, udate client file
20
+ ([`37f0024`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/37f002427ad5da01164ae3b0f4983695fe61c243))
21
+
22
+ - **bec-status-box**: Add get_server_state user_access method to BECStatusBox
23
+ ([`1619446`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/1619446ec9839cfa1c666a3790a0c2abc449c4a8))
24
+
25
+
4
26
  ## v2.1.1 (2025-05-06)
5
27
 
6
28
  ### Bug Fixes
PKG-INFO CHANGED
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bec_widgets
3
- Version: 2.1.1
3
+ Version: 2.1.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
bec_widgets/cli/client.py CHANGED
@@ -470,6 +470,12 @@ class BECProgressBar(RPCBase):
470
470
  >>> progressbar.label_template = "$value / $percentage %"
471
471
  """
472
472
 
473
+ @rpc_call
474
+ def _get_label(self) -> str:
475
+ """
476
+ Return the label text. mostly used for testing rpc.
477
+ """
478
+
473
479
 
474
480
  class BECQueue(RPCBase):
475
481
  """Widget to display the BEC queue."""
@@ -484,6 +490,12 @@ class BECQueue(RPCBase):
484
490
  class BECStatusBox(RPCBase):
485
491
  """An autonomous widget to display the status of BEC services."""
486
492
 
493
+ @rpc_call
494
+ def get_server_state(self) -> "str":
495
+ """
496
+ Get the state ("RUNNING", "BUSY", "IDLE", "ERROR") of the BEC server
497
+ """
498
+
487
499
  @rpc_call
488
500
  def remove(self):
489
501
  """
@@ -25,10 +25,20 @@ if TYPE_CHECKING: # pragma: no cover
25
25
 
26
26
 
27
27
  class QtThreadSafeCallback(QObject):
28
+ """QtThreadSafeCallback is a wrapper around a callback function to make it thread-safe for Qt."""
29
+
28
30
  cb_signal = pyqtSignal(dict, dict)
29
31
 
30
- def __init__(self, cb):
32
+ def __init__(self, cb: Callable, cb_info: dict | None = None):
33
+ """
34
+ Initialize the QtThreadSafeCallback.
35
+
36
+ Args:
37
+ cb (Callable): The callback function to be wrapped.
38
+ cb_info (dict, optional): Additional information about the callback. Defaults to None.
39
+ """
31
40
  super().__init__()
41
+ self.cb_info = cb_info
32
42
 
33
43
  self.cb = cb
34
44
  self.cb_signal.connect(self.cb)
@@ -37,7 +47,7 @@ class QtThreadSafeCallback(QObject):
37
47
  # make 2 differents QtThreadSafeCallback to look
38
48
  # identical when used as dictionary keys, if the
39
49
  # callback is the same
40
- return id(self.cb)
50
+ return f"{id(self.cb)}{self.cb_info}".__hash__()
41
51
 
42
52
  def __call__(self, msg_content, metadata):
43
53
  self.cb_signal.emit(msg_content, metadata)
@@ -141,6 +151,7 @@ class BECDispatcher:
141
151
  self,
142
152
  slot: Callable,
143
153
  topics: Union[EndpointInfo, str, list[Union[EndpointInfo, str]]],
154
+ cb_info: dict | None = None,
144
155
  **kwargs,
145
156
  ) -> None:
146
157
  """Connect widget's qt slot, so that it is called on new pub/sub topic message.
@@ -149,8 +160,9 @@ class BECDispatcher:
149
160
  slot (Callable): A slot method/function that accepts two inputs: content and metadata of
150
161
  the corresponding pub/sub message
151
162
  topics (EndpointInfo | str | list): A topic or list of topics that can typically be acquired via bec_lib.MessageEndpoints
163
+ cb_info (dict | None): A dictionary containing information about the callback. Defaults to None.
152
164
  """
153
- slot = QtThreadSafeCallback(slot)
165
+ slot = QtThreadSafeCallback(cb=slot, cb_info=cb_info)
154
166
  self.client.connector.register(topics, cb=slot, **kwargs)
155
167
  topics_str, _ = self.client.connector._convert_endpointinfo(topics)
156
168
  self._slots[slot].update(set(topics_str))
@@ -1182,10 +1182,11 @@ class Waveform(PlotBase):
1182
1182
  self.on_async_readback,
1183
1183
  MessageEndpoints.device_async_readback(self.scan_id, name),
1184
1184
  from_start=True,
1185
+ cb_info={"scan_id": self.scan_id},
1185
1186
  )
1186
1187
  logger.info(f"Setup async curve {name}")
1187
1188
 
1188
- @SafeSlot(dict, dict)
1189
+ @SafeSlot(dict, dict, verify_sender=True)
1189
1190
  def on_async_readback(self, msg, metadata):
1190
1191
  """
1191
1192
  Get async data readback. This code needs to be fast, therefor we try
@@ -1204,6 +1205,14 @@ class Waveform(PlotBase):
1204
1205
  msg(dict): Message with the async data.
1205
1206
  metadata(dict): Metadata of the message.
1206
1207
  """
1208
+ sender = self.sender()
1209
+ if not hasattr(sender, "cb_info"):
1210
+ logger.info(f"Sender {sender} has no cb_info.")
1211
+ return
1212
+ scan_id = sender.cb_info.get("scan_id", None)
1213
+ if scan_id != self.scan_id:
1214
+ logger.info("Scan ID mismatch, ignoring async readback.")
1215
+
1207
1216
  instruction = metadata.get("async_update", {}).get("type")
1208
1217
  if instruction not in ["add", "add_slice", "replace"]:
1209
1218
  logger.warning(f"Invalid async update instruction: {instruction}")
@@ -1212,6 +1221,7 @@ class Waveform(PlotBase):
1212
1221
  plot_mode = self.x_axis_mode["name"]
1213
1222
  for curve in self._async_curves:
1214
1223
  x_data = None # Reset x_data
1224
+ y_data = None # Reset y_data
1215
1225
  # Get the curve data
1216
1226
  async_data = msg["signals"].get(curve.config.signal.entry, None)
1217
1227
  if async_data is None:
@@ -21,6 +21,7 @@ class BECProgressBar(BECWidget, QWidget):
21
21
  "set_minimum",
22
22
  "label_template",
23
23
  "label_template.setter",
24
+ "_get_label",
24
25
  ]
25
26
  ICON_NAME = "page_control"
26
27
 
@@ -235,6 +236,10 @@ class BECProgressBar(BECWidget, QWidget):
235
236
  (value - self._user_minimum) / (self._user_maximum - self._user_minimum) * self._maximum
236
237
  )
237
238
 
239
+ def _get_label(self) -> str:
240
+ """Return the label text. mostly used for testing rpc."""
241
+ return self.center_label.text()
242
+
238
243
 
239
244
  if __name__ == "__main__": # pragma: no cover
240
245
  app = QApplication(sys.argv)
@@ -76,6 +76,7 @@ class BECStatusBox(BECWidget, CompactPopupWidget):
76
76
 
77
77
  PLUGIN = True
78
78
  CORE_SERVICES = ["DeviceServer", "ScanServer", "SciHub", "ScanBundler", "FileWriterManager"]
79
+ USER_ACCESS = ["get_server_state", "remove"]
79
80
 
80
81
  service_update = Signal(BECServiceInfoContainer)
81
82
  bec_core_state = Signal(str)
@@ -134,6 +135,10 @@ class BECStatusBox(BECWidget, CompactPopupWidget):
134
135
  "QTreeWidget::item:selected {}"
135
136
  )
136
137
 
138
+ def get_server_state(self) -> str:
139
+ """Get the state ("RUNNING", "BUSY", "IDLE", "ERROR") of the BEC server"""
140
+ return self.status_container[self.box_name]["info"].status
141
+
137
142
  def _create_status_widget(
138
143
  self, service_name: str, status=BECStatus, info: dict = None, metrics: dict = None
139
144
  ) -> StatusItem:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bec_widgets
3
- Version: 2.1.1
3
+ Version: 2.1.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
@@ -1,12 +1,12 @@
1
1
  .gitignore,sha256=cMQ1MLmnoR88aMCCJwUyfoTnufzl4-ckmHtlFUqHcT4,3253
2
- .gitlab-ci.yml,sha256=tMIfjmYyVstGlMLmmCpRSDE26p6aIC81y0tQobRoPK8,9523
2
+ .gitlab-ci.yml,sha256=1nMYldzVk0tFkBWYTcUjumOrdSADASheWOAc0kOFDYs,9509
3
3
  .pylintrc,sha256=eeY8YwSI74oFfq6IYIbCqnx3Vk8ZncKaatv96n_Y8Rs,18544
4
4
  .readthedocs.yaml,sha256=aSOc277LqXcsTI6lgvm_JY80lMlr69GbPKgivua2cS0,603
5
- CHANGELOG.md,sha256=Vuwr3XzWEJO3VHCYZ3mjbb8RLw3-vxwK8vx0L3KmnJA,270596
5
+ CHANGELOG.md,sha256=-NKbjMkJw5Y_NGzR5o_NSDUEBJk2lbLqIbrlq0EKzps,271406
6
6
  LICENSE,sha256=YRKe85CBRyP7UpEAWwU8_qSIyuy5-l_9C-HKg5Qm8MQ,1511
7
- PKG-INFO,sha256=bEgpqj6pSAxj09JECN_HbmbgYC1RdfBQW45TfRgb9JQ,1224
7
+ PKG-INFO,sha256=5sfOavPZf4UvV9AqHkiwbsUmR1ANqIBkHSMDcMKRdO0,1224
8
8
  README.md,sha256=KgdKusjlvEvFtdNZCeDMO91y77MWK2iDcYMDziksOr4,2553
9
- pyproject.toml,sha256=E57kZOsmmdQerKWdTuF7CSqBB3Cu3TyZeXxZl40kVtI,2568
9
+ pyproject.toml,sha256=BqRAPn18d8SH92IHfQeZcguEYPoXMIptC2JFn-Y-M6w,2568
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
@@ -22,7 +22,7 @@ bec_widgets/assets/app_icons/auto_update.png,sha256=YKoAJTWAlWzreYvOm0BttDRFr29t
22
22
  bec_widgets/assets/app_icons/bec_widgets_icon.png,sha256=K8dgGwIjalDh9PRHUsSQBqgdX7a00nM3igZdc20pkYM,1747017
23
23
  bec_widgets/assets/app_icons/ui_loader_tile.png,sha256=qSK3XHqvnAVGV9Q0ulORcGFbXJ9LDq2uz8l9uTtMsNk,1812476
24
24
  bec_widgets/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
25
- bec_widgets/cli/client.py,sha256=DDxJ85yL-X2UPc2kEw29kDq598imXZEDw1MXeBJNGf0,80061
25
+ bec_widgets/cli/client.py,sha256=2Z0ihxMONJChLuhMxaRon0gNsnbuhTz4jlsSg-xAKEk,80350
26
26
  bec_widgets/cli/client_utils.py,sha256=F2hyt--jL53bN8NoWifNUMqwwx5FbpS6I1apERdTRzM,18114
27
27
  bec_widgets/cli/generate_cli.py,sha256=xcPNyJoa3IjddX1yEDY45tT-Cs4jO5cQLUmcEubKs44,10976
28
28
  bec_widgets/cli/server.py,sha256=lYEkOaokLbND4KjbXyySzb5nq3YQ6m4L0NAmHAjMCIU,5633
@@ -49,7 +49,7 @@ bec_widgets/tests/utils.py,sha256=GbQtN7qf9n-8FoAfNddZ4aAqA7oBo_hGAlnKELd6Xzw,69
49
49
  bec_widgets/utils/__init__.py,sha256=1930ji1Jj6dVuY81Wd2kYBhHYNV-2R0bN_L4o9zBj1U,533
50
50
  bec_widgets/utils/bec_connector.py,sha256=Ao_DN6oiHlpbVDHDK0RLpAgz2zDbhmwYee8yc3y7m2g,18875
51
51
  bec_widgets/utils/bec_designer.py,sha256=ehNl_i743rijmhPiIGNd1bihE7-l4oJzTVoa4yjPjls,5426
52
- bec_widgets/utils/bec_dispatcher.py,sha256=R0TDylR1ghYzNZj_1DavAEvswbK3iD1bI9IcWWwzhMc,8374
52
+ bec_widgets/utils/bec_dispatcher.py,sha256=Zv2D0Ah0ZmXBNk8AbdHD2osHgTXqkvw51I_iCrSmVYA,8990
53
53
  bec_widgets/utils/bec_plugin_helper.py,sha256=efg97QDAqhZYeqE1wk3vEgkFuhNewg4rvJrtB7mRCAE,3139
54
54
  bec_widgets/utils/bec_signal_proxy.py,sha256=Yc08fdBEDABrowwNPSngT9-28R8FD4ml7oTL6BoMyEE,3263
55
55
  bec_widgets/utils/bec_table.py,sha256=nA2b8ukSeUfquFMAxGrUVOqdrzMoDYD6O_4EYbOG2zk,717
@@ -293,7 +293,7 @@ bec_widgets/widgets/plots/toolbar_bundles/save_state.py,sha256=H3fu-bRzNIycCUFb2
293
293
  bec_widgets/widgets/plots/waveform/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
294
294
  bec_widgets/widgets/plots/waveform/curve.py,sha256=KlcGbd60lPO9BYcca08fMhWkfx5qu4O9IbSNTwvajGM,10401
295
295
  bec_widgets/widgets/plots/waveform/register_waveform.py,sha256=pdcLCYKkLkSb-5DqbJdC6M3JyoXQBRVAKf7BZVCto80,467
296
- bec_widgets/widgets/plots/waveform/waveform.py,sha256=6Yo4AhUh5-mu3_OH8yHnAS00B_6SWDFZtm0hCz5fcwE,68057
296
+ bec_widgets/widgets/plots/waveform/waveform.py,sha256=RvdHWyWVl6_xaLclts2GoKsWvTqHEvJKBpq2gley2xA,68480
297
297
  bec_widgets/widgets/plots/waveform/waveform.pyproject,sha256=X2T6d4JGt9YSI28e-myjXh1YkUM4Yr3kNb0-F84KvUA,26
298
298
  bec_widgets/widgets/plots/waveform/waveform_plugin.py,sha256=2AZPtBHs75l9cdhwQnY3jpIMRPUUqK3RNvQbTvrFyvg,1237
299
299
  bec_widgets/widgets/plots/waveform/settings/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -306,7 +306,7 @@ bec_widgets/widgets/progress/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NM
306
306
  bec_widgets/widgets/progress/bec_progressbar/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
307
307
  bec_widgets/widgets/progress/bec_progressbar/bec_progress_bar.pyproject,sha256=Pb3n9seM95_8myKJ0pv_9IcfJDNJJNOFBskuRdEVzhU,33
308
308
  bec_widgets/widgets/progress/bec_progressbar/bec_progress_bar_plugin.py,sha256=_iVMn5G2detLmYxVzY-rwUBY2S8CWF4TSrjlEcs4LOs,1361
309
- bec_widgets/widgets/progress/bec_progressbar/bec_progressbar.py,sha256=DS4W5BQqdN2s-8zMaA7NdpVsrn_EH5lvEjsGnVTGn0k,7987
309
+ bec_widgets/widgets/progress/bec_progressbar/bec_progressbar.py,sha256=W0EXctfBgt9mGKlNa2fa7ucfXhljEG2p5_s3iKT_atI,8149
310
310
  bec_widgets/widgets/progress/bec_progressbar/register_bec_progress_bar.py,sha256=HLXS4ctm-mL6QRtG8yjplsywAXXelDJv2kwUUOgfi2o,514
311
311
  bec_widgets/widgets/progress/ring_progress_bar/__init__.py,sha256=_uoJKnDM2YAeUBfwc5WLbIHSJj7zm_FAurSKP3WRaCw,47
312
312
  bec_widgets/widgets/progress/ring_progress_bar/register_ring_progress_bar.py,sha256=83PNZ-m5VqlAH51RCDtKN9hK2GVbrmiepFJzR7SvR64,519
@@ -321,7 +321,7 @@ bec_widgets/widgets/services/bec_queue/bec_queue.pyproject,sha256=VhoNmAv1DQUl9d
321
321
  bec_widgets/widgets/services/bec_queue/bec_queue_plugin.py,sha256=0gznimXzpfJYQ5NWw9Ryulr7ZFwoi6c14Ri-Y16F9Sw,1350
322
322
  bec_widgets/widgets/services/bec_queue/register_bec_queue.py,sha256=MHPwjb4Hcg0Qp-F4ID6ZTXaMrtpmgLagHTaacOTxPqA,472
323
323
  bec_widgets/widgets/services/bec_status_box/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
324
- bec_widgets/widgets/services/bec_status_box/bec_status_box.py,sha256=Iw69xY0NvR4ezqU3YB101x0X0rTlkoo3QyTqez9qKPs,13282
324
+ bec_widgets/widgets/services/bec_status_box/bec_status_box.py,sha256=fS55Z9QByVgCoM1CJBXvPCmWctCmYiu20lbLpDqrdUs,13521
325
325
  bec_widgets/widgets/services/bec_status_box/bec_status_box.pyproject,sha256=JWtx3Csfn2h7ODtk10HtyBNLf6tFIqyU6g04rMWOO1U,32
326
326
  bec_widgets/widgets/services/bec_status_box/bec_status_box_plugin.py,sha256=2tBPwcEIlQa_fH9lNiwgSqzU23g8VSwEvNvTVmHQA_U,1421
327
327
  bec_widgets/widgets/services/bec_status_box/register_bec_status_box.py,sha256=_1gr5nid6D5ZEvvt-GPyXhEGfacSh_QW0oWKxmZrUmY,490
@@ -377,8 +377,8 @@ bec_widgets/widgets/utility/visual/dark_mode_button/dark_mode_button.py,sha256=O
377
377
  bec_widgets/widgets/utility/visual/dark_mode_button/dark_mode_button.pyproject,sha256=Lbi9zb6HNlIq14k6hlzR-oz6PIFShBuF7QxE6d87d64,34
378
378
  bec_widgets/widgets/utility/visual/dark_mode_button/dark_mode_button_plugin.py,sha256=CzChz2SSETYsR8-36meqWnsXCT-FIy_J_xeU5coWDY8,1350
379
379
  bec_widgets/widgets/utility/visual/dark_mode_button/register_dark_mode_button.py,sha256=rMpZ1CaoucwobgPj1FuKTnt07W82bV1GaSYdoqcdMb8,521
380
- bec_widgets-2.1.1.dist-info/METADATA,sha256=bEgpqj6pSAxj09JECN_HbmbgYC1RdfBQW45TfRgb9JQ,1224
381
- bec_widgets-2.1.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
382
- bec_widgets-2.1.1.dist-info/entry_points.txt,sha256=dItMzmwA1wizJ1Itx15qnfJ0ZzKVYFLVJ1voxT7K7D4,214
383
- bec_widgets-2.1.1.dist-info/licenses/LICENSE,sha256=YRKe85CBRyP7UpEAWwU8_qSIyuy5-l_9C-HKg5Qm8MQ,1511
384
- bec_widgets-2.1.1.dist-info/RECORD,,
380
+ bec_widgets-2.1.2.dist-info/METADATA,sha256=5sfOavPZf4UvV9AqHkiwbsUmR1ANqIBkHSMDcMKRdO0,1224
381
+ bec_widgets-2.1.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
382
+ bec_widgets-2.1.2.dist-info/entry_points.txt,sha256=dItMzmwA1wizJ1Itx15qnfJ0ZzKVYFLVJ1voxT7K7D4,214
383
+ bec_widgets-2.1.2.dist-info/licenses/LICENSE,sha256=YRKe85CBRyP7UpEAWwU8_qSIyuy5-l_9C-HKg5Qm8MQ,1511
384
+ bec_widgets-2.1.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 = "2.1.1"
7
+ version = "2.1.2"
8
8
  description = "BEC Widgets"
9
9
  requires-python = ">=3.10"
10
10
  classifiers = [