bec-ipython-client 3.77.1__tar.gz → 3.78.1__tar.gz
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.
- {bec_ipython_client-3.77.1 → bec_ipython_client-3.78.1}/PKG-INFO +1 -1
- {bec_ipython_client-3.77.1 → bec_ipython_client-3.78.1}/bec_ipython_client/main.py +65 -6
- {bec_ipython_client-3.77.1 → bec_ipython_client-3.78.1}/pyproject.toml +1 -1
- {bec_ipython_client-3.77.1 → bec_ipython_client-3.78.1}/tests/client_tests/test_bec_client.py +31 -0
- {bec_ipython_client-3.77.1 → bec_ipython_client-3.78.1}/.gitignore +0 -0
- {bec_ipython_client-3.77.1 → bec_ipython_client-3.78.1}/bec_ipython_client/__init__.py +0 -0
- {bec_ipython_client-3.77.1 → bec_ipython_client-3.78.1}/bec_ipython_client/beamline_mixin.py +0 -0
- {bec_ipython_client-3.77.1 → bec_ipython_client-3.78.1}/bec_ipython_client/bec_magics.py +0 -0
- {bec_ipython_client-3.77.1 → bec_ipython_client-3.78.1}/bec_ipython_client/bec_startup.py +0 -0
- {bec_ipython_client-3.77.1 → bec_ipython_client-3.78.1}/bec_ipython_client/callbacks/__init__.py +0 -0
- {bec_ipython_client-3.77.1 → bec_ipython_client-3.78.1}/bec_ipython_client/callbacks/device_progress.py +0 -0
- {bec_ipython_client-3.77.1 → bec_ipython_client-3.78.1}/bec_ipython_client/callbacks/ipython_live_updates.py +0 -0
- {bec_ipython_client-3.77.1 → bec_ipython_client-3.78.1}/bec_ipython_client/callbacks/live_table.py +0 -0
- {bec_ipython_client-3.77.1 → bec_ipython_client-3.78.1}/bec_ipython_client/callbacks/move_device.py +0 -0
- {bec_ipython_client-3.77.1 → bec_ipython_client-3.78.1}/bec_ipython_client/callbacks/utils.py +0 -0
- {bec_ipython_client-3.77.1 → bec_ipython_client-3.78.1}/bec_ipython_client/high_level_interfaces/__init__.py +0 -0
- {bec_ipython_client-3.77.1 → bec_ipython_client-3.78.1}/bec_ipython_client/high_level_interfaces/bec_hli.py +0 -0
- {bec_ipython_client-3.77.1 → bec_ipython_client-3.78.1}/bec_ipython_client/high_level_interfaces/spec_hli.py +0 -0
- {bec_ipython_client-3.77.1 → bec_ipython_client-3.78.1}/bec_ipython_client/plugins/SLS/__init__.py +0 -0
- {bec_ipython_client-3.77.1 → bec_ipython_client-3.78.1}/bec_ipython_client/plugins/SLS/sls_info.py +0 -0
- {bec_ipython_client-3.77.1 → bec_ipython_client-3.78.1}/bec_ipython_client/plugins/XTreme/__init__.py +0 -0
- {bec_ipython_client-3.77.1 → bec_ipython_client-3.78.1}/bec_ipython_client/plugins/XTreme/x-treme.py +0 -0
- {bec_ipython_client-3.77.1 → bec_ipython_client-3.78.1}/bec_ipython_client/plugins/__init__.py +0 -0
- {bec_ipython_client-3.77.1 → bec_ipython_client-3.78.1}/bec_ipython_client/plugins/flomni/flomni_config.yaml +0 -0
- {bec_ipython_client-3.77.1 → bec_ipython_client-3.78.1}/bec_ipython_client/prettytable.py +0 -0
- {bec_ipython_client-3.77.1 → bec_ipython_client-3.78.1}/bec_ipython_client/progressbar.py +0 -0
- {bec_ipython_client-3.77.1 → bec_ipython_client-3.78.1}/bec_ipython_client/signals.py +0 -0
- {bec_ipython_client-3.77.1 → bec_ipython_client-3.78.1}/demo.py +0 -0
- {bec_ipython_client-3.77.1 → bec_ipython_client-3.78.1}/tests/client_tests/conftest.py +0 -0
- {bec_ipython_client-3.77.1 → bec_ipython_client-3.78.1}/tests/client_tests/test_beamline_mixins.py +0 -0
- {bec_ipython_client-3.77.1 → bec_ipython_client-3.78.1}/tests/client_tests/test_device_progress.py +0 -0
- {bec_ipython_client-3.77.1 → bec_ipython_client-3.78.1}/tests/client_tests/test_ipython_live_updates.py +0 -0
- {bec_ipython_client-3.77.1 → bec_ipython_client-3.78.1}/tests/client_tests/test_live_table.py +0 -0
- {bec_ipython_client-3.77.1 → bec_ipython_client-3.78.1}/tests/client_tests/test_move_callback.py +0 -0
- {bec_ipython_client-3.77.1 → bec_ipython_client-3.78.1}/tests/client_tests/test_pretty_table.py +0 -0
- {bec_ipython_client-3.77.1 → bec_ipython_client-3.78.1}/tests/conftest.py +0 -0
- {bec_ipython_client-3.77.1 → bec_ipython_client-3.78.1}/tests/end-2-end/_ensure_requirements_container.py +0 -0
- {bec_ipython_client-3.77.1 → bec_ipython_client-3.78.1}/tests/end-2-end/test_procedures_e2e.py +0 -0
- {bec_ipython_client-3.77.1 → bec_ipython_client-3.78.1}/tests/end-2-end/test_scans_e2e.py +0 -0
- {bec_ipython_client-3.77.1 → bec_ipython_client-3.78.1}/tests/end-2-end/test_scans_lib_e2e.py +0 -0
|
@@ -1,4 +1,8 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
import argparse
|
|
4
|
+
import collections
|
|
5
|
+
import functools
|
|
2
6
|
import os
|
|
3
7
|
import sys
|
|
4
8
|
from importlib.metadata import version
|
|
@@ -7,16 +11,17 @@ from typing import Iterable, Literal, Tuple
|
|
|
7
11
|
import IPython
|
|
8
12
|
import redis
|
|
9
13
|
import redis.exceptions
|
|
10
|
-
import requests
|
|
11
14
|
from IPython.terminal.ipapp import TerminalIPythonApp
|
|
12
15
|
from IPython.terminal.prompts import Prompts, Token
|
|
16
|
+
from rich.console import Console
|
|
17
|
+
from rich.panel import Panel
|
|
18
|
+
from rich.text import Text
|
|
13
19
|
|
|
14
20
|
from bec_ipython_client.beamline_mixin import BeamlineMixin
|
|
15
21
|
from bec_ipython_client.bec_magics import BECMagics
|
|
16
22
|
from bec_ipython_client.callbacks.ipython_live_updates import IPythonLiveUpdates
|
|
17
23
|
from bec_ipython_client.signals import ScanInterruption, SigintHandler
|
|
18
24
|
from bec_lib import plugin_helper
|
|
19
|
-
from bec_lib.acl_login import BECAuthenticationError
|
|
20
25
|
from bec_lib.alarm_handler import AlarmBase
|
|
21
26
|
from bec_lib.bec_errors import DeviceConfigError
|
|
22
27
|
from bec_lib.bec_service import parse_cmdline_args
|
|
@@ -79,6 +84,7 @@ class BECIPythonClient:
|
|
|
79
84
|
self._client.callbacks.register(
|
|
80
85
|
event_type=EventType.NAMESPACE_UPDATE, callback=self._update_namespace_callback
|
|
81
86
|
)
|
|
87
|
+
self._alarm_history = collections.deque(maxlen=100)
|
|
82
88
|
|
|
83
89
|
def __getattr__(self, name):
|
|
84
90
|
return getattr(self._client, name)
|
|
@@ -136,7 +142,7 @@ class BECIPythonClient:
|
|
|
136
142
|
self._refresh_ipython_username()
|
|
137
143
|
self._load_magics()
|
|
138
144
|
self._ip.events.register("post_run_cell", log_console)
|
|
139
|
-
self._ip.set_custom_exc((Exception,),
|
|
145
|
+
self._ip.set_custom_exc((Exception,), self._create_exception_handler())
|
|
140
146
|
# represent objects using __str__, if overwritten, otherwise use __repr__
|
|
141
147
|
self._ip.display_formatter.formatters["text/plain"].for_type(
|
|
142
148
|
object,
|
|
@@ -187,10 +193,63 @@ class BECIPythonClient:
|
|
|
187
193
|
pass
|
|
188
194
|
self._client.shutdown()
|
|
189
195
|
|
|
196
|
+
def _create_exception_handler(self):
|
|
197
|
+
return functools.partial(_ip_exception_handler, parent=self)
|
|
190
198
|
|
|
191
|
-
def
|
|
192
|
-
|
|
193
|
-
|
|
199
|
+
def show_last_alarm(self, offset: int = 0):
|
|
200
|
+
"""
|
|
201
|
+
Show the last alarm raised in this session with rich formatting.
|
|
202
|
+
"""
|
|
203
|
+
try:
|
|
204
|
+
alarm: AlarmBase = self._alarm_history[-1 - offset][1]
|
|
205
|
+
except IndexError:
|
|
206
|
+
print("No alarm has been raised in this session.")
|
|
207
|
+
return
|
|
208
|
+
|
|
209
|
+
console = Console()
|
|
210
|
+
|
|
211
|
+
# --- HEADER ---
|
|
212
|
+
header = Text()
|
|
213
|
+
header.append("Alarm Raised\n", style="bold red")
|
|
214
|
+
header.append(f"Severity: {alarm.severity.name}\n", style="bold")
|
|
215
|
+
header.append(f"Type: {alarm.alarm_type}\n", style="bold")
|
|
216
|
+
if alarm.alarm.source.get("device"):
|
|
217
|
+
header.append(f"Device: {alarm.alarm.source['device']}\n", style="bold")
|
|
218
|
+
|
|
219
|
+
console.print(Panel(header, title="Alarm Info", border_style="red", expand=False))
|
|
220
|
+
|
|
221
|
+
# --- SHOW SUMMARY
|
|
222
|
+
if alarm.alarm.compact_msg:
|
|
223
|
+
console.print(
|
|
224
|
+
Panel(
|
|
225
|
+
Text(alarm.alarm.compact_msg, style="yellow"),
|
|
226
|
+
title="Summary",
|
|
227
|
+
border_style="yellow",
|
|
228
|
+
expand=False,
|
|
229
|
+
)
|
|
230
|
+
)
|
|
231
|
+
|
|
232
|
+
# --- SHOW FULL TRACEBACK
|
|
233
|
+
tb_str = alarm.alarm.msg
|
|
234
|
+
if tb_str:
|
|
235
|
+
try:
|
|
236
|
+
console.print(tb_str)
|
|
237
|
+
except Exception:
|
|
238
|
+
# fallback in case msg is not a traceback
|
|
239
|
+
console.print(Panel(tb_str, title="Message", border_style="cyan"))
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
def _ip_exception_handler(
|
|
243
|
+
self, etype, evalue, tb, tb_offset=None, parent: BECIPythonClient = None, **kwargs
|
|
244
|
+
):
|
|
245
|
+
if issubclass(etype, AlarmBase):
|
|
246
|
+
parent._alarm_history.append((etype, evalue, tb, tb_offset))
|
|
247
|
+
print("\x1b[31m BEC alarm:\x1b[0m")
|
|
248
|
+
evalue.pretty_print()
|
|
249
|
+
print("For more details, use 'bec.show_last_alarm()'")
|
|
250
|
+
return
|
|
251
|
+
if issubclass(etype, (ScanInterruption, DeviceConfigError)):
|
|
252
|
+
print(f"\x1b[31m {evalue.__class__.__name__}:\x1b[0m {evalue}")
|
|
194
253
|
return
|
|
195
254
|
if issubclass(etype, redis.exceptions.NoPermissionError):
|
|
196
255
|
# pylint: disable=protected-access
|
{bec_ipython_client-3.77.1 → bec_ipython_client-3.78.1}/tests/client_tests/test_bec_client.py
RENAMED
|
@@ -7,6 +7,7 @@ import pytest
|
|
|
7
7
|
|
|
8
8
|
from bec_ipython_client import BECIPythonClient, main
|
|
9
9
|
from bec_lib import messages
|
|
10
|
+
from bec_lib.alarm_handler import AlarmBase, AlarmHandler, Alarms
|
|
10
11
|
from bec_lib.redis_connector import RedisConnector
|
|
11
12
|
from bec_lib.service_config import ServiceConfig
|
|
12
13
|
|
|
@@ -211,3 +212,33 @@ def test_bec_ipython_client_property_access(ipython_client):
|
|
|
211
212
|
client.active_account = "account"
|
|
212
213
|
with pytest.raises(AttributeError):
|
|
213
214
|
client._client.active_account = "account"
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
def test_bec_ipython_client_show_last_alarm(ipython_client, capsys):
|
|
218
|
+
client = ipython_client
|
|
219
|
+
alarm_msg = messages.AlarmMessage(
|
|
220
|
+
severity=Alarms.MAJOR,
|
|
221
|
+
alarm_type="TestAlarm",
|
|
222
|
+
source={},
|
|
223
|
+
msg="This is a test alarm",
|
|
224
|
+
compact_msg="Test alarm",
|
|
225
|
+
)
|
|
226
|
+
client.alarm_handler = AlarmHandler(connector=mock.MagicMock())
|
|
227
|
+
client.alarm_handler.add_alarm(alarm_msg)
|
|
228
|
+
client._alarm_history.append(
|
|
229
|
+
(AlarmBase, client.alarm_handler.get_unhandled_alarms()[0], None, None)
|
|
230
|
+
)
|
|
231
|
+
client.show_last_alarm()
|
|
232
|
+
captured = capsys.readouterr()
|
|
233
|
+
assert "Alarm Raised" in captured.out
|
|
234
|
+
assert "Severity: MAJOR" in captured.out
|
|
235
|
+
assert "Type: TestAlarm" in captured.out
|
|
236
|
+
assert "This is a test alarm" in captured.out
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
def test_bec_ipython_client_show_last_no_alarm(ipython_client, capsys):
|
|
240
|
+
client = ipython_client
|
|
241
|
+
client._alarm_history = []
|
|
242
|
+
client.show_last_alarm()
|
|
243
|
+
captured = capsys.readouterr()
|
|
244
|
+
assert "No alarm has been raised in this session." in captured.out
|
|
File without changes
|
|
File without changes
|
{bec_ipython_client-3.77.1 → bec_ipython_client-3.78.1}/bec_ipython_client/beamline_mixin.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{bec_ipython_client-3.77.1 → bec_ipython_client-3.78.1}/bec_ipython_client/callbacks/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{bec_ipython_client-3.77.1 → bec_ipython_client-3.78.1}/bec_ipython_client/callbacks/live_table.py
RENAMED
|
File without changes
|
{bec_ipython_client-3.77.1 → bec_ipython_client-3.78.1}/bec_ipython_client/callbacks/move_device.py
RENAMED
|
File without changes
|
{bec_ipython_client-3.77.1 → bec_ipython_client-3.78.1}/bec_ipython_client/callbacks/utils.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{bec_ipython_client-3.77.1 → bec_ipython_client-3.78.1}/bec_ipython_client/plugins/SLS/__init__.py
RENAMED
|
File without changes
|
{bec_ipython_client-3.77.1 → bec_ipython_client-3.78.1}/bec_ipython_client/plugins/SLS/sls_info.py
RENAMED
|
File without changes
|
|
File without changes
|
{bec_ipython_client-3.77.1 → bec_ipython_client-3.78.1}/bec_ipython_client/plugins/XTreme/x-treme.py
RENAMED
|
File without changes
|
{bec_ipython_client-3.77.1 → bec_ipython_client-3.78.1}/bec_ipython_client/plugins/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{bec_ipython_client-3.77.1 → bec_ipython_client-3.78.1}/tests/client_tests/test_beamline_mixins.py
RENAMED
|
File without changes
|
{bec_ipython_client-3.77.1 → bec_ipython_client-3.78.1}/tests/client_tests/test_device_progress.py
RENAMED
|
File without changes
|
|
File without changes
|
{bec_ipython_client-3.77.1 → bec_ipython_client-3.78.1}/tests/client_tests/test_live_table.py
RENAMED
|
File without changes
|
{bec_ipython_client-3.77.1 → bec_ipython_client-3.78.1}/tests/client_tests/test_move_callback.py
RENAMED
|
File without changes
|
{bec_ipython_client-3.77.1 → bec_ipython_client-3.78.1}/tests/client_tests/test_pretty_table.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{bec_ipython_client-3.77.1 → bec_ipython_client-3.78.1}/tests/end-2-end/test_procedures_e2e.py
RENAMED
|
File without changes
|
|
File without changes
|
{bec_ipython_client-3.77.1 → bec_ipython_client-3.78.1}/tests/end-2-end/test_scans_lib_e2e.py
RENAMED
|
File without changes
|