0
0
mirror of https://github.com/bec-project/bec_widgets.git synced 2025-07-13 11:11:49 +02:00

refactor(logger): changed prints to logger calls

This commit is contained in:
2024-09-03 20:08:35 +02:00
parent 814c823875
commit 3a5d7d0796
18 changed files with 99 additions and 52 deletions

View File

@ -80,7 +80,7 @@ def _get_output(process, logger) -> None:
buf.clear()
buf.append(remaining)
except Exception as e:
print(f"Error reading process output: {str(e)}")
logger.error(f"Error reading process output: {str(e)}")
def _start_plot_process(gui_id: str, gui_class: type, config: dict | str, logger=None) -> None:
@ -146,7 +146,7 @@ class BECGuiClientMixin:
continue
return ep.load()(gui=self)
except Exception as e:
print(f"Error loading auto update script from plugin: {str(e)}")
logger.error(f"Error loading auto update script from plugin: {str(e)}")
return None
@property
@ -189,11 +189,12 @@ class BECGuiClientMixin:
if self._process is None or self._process.poll() is not None:
self._start_update_script()
self._process, self._process_output_processing_thread = _start_plot_process(
self._gui_id, self.__class__, self._client._service_config.config
self._gui_id, self.__class__, self._client._service_config.config, logger=logger
)
while not self.gui_is_alive():
print("Waiting for GUI to start...")
time.sleep(1)
logger.success(f"GUI started with id: {self._gui_id}")
def close(self) -> None:
"""
@ -226,7 +227,7 @@ class RPCBase:
def __init__(self, gui_id: str = None, config: dict = None, parent=None) -> None:
self._client = BECClient() # BECClient is a singleton; here, we simply get the instance
self._config = config if config is not None else {}
self._gui_id = gui_id if gui_id is not None else str(uuid.uuid4())
self._gui_id = gui_id if gui_id is not None else str(uuid.uuid4())[:5]
self._parent = parent
self._msg_wait_event = threading.Event()
self._rpc_response = None

View File

@ -53,9 +53,11 @@ class BECWidgetsCLIServer:
self._heartbeat_timer.start(200)
self.status = messages.BECStatus.RUNNING
logger.success(f"Server started with gui_id: {self.gui_id}")
def on_rpc_update(self, msg: dict, metadata: dict):
request_id = metadata.get("request_id")
logger.debug(f"Received RPC instruction: {msg}, metadata: {metadata}")
try:
obj = self.get_object_from_config(msg["parameter"])
method = msg["action"]
@ -63,9 +65,10 @@ class BECWidgetsCLIServer:
kwargs = msg["parameter"].get("kwargs", {})
res = self.run_rpc(obj, method, args, kwargs)
except Exception as e:
print(e)
logger.error(f"Error while executing RPC instruction: {e}")
self.send_response(request_id, False, {"error": str(e)})
else:
logger.debug(f"RPC instruction executed successfully: {res}")
self.send_response(request_id, True, {"result": res})
def send_response(self, request_id: str, accepted: bool, msg: dict):
@ -113,6 +116,7 @@ class BECWidgetsCLIServer:
return obj
def emit_heartbeat(self):
logger.trace(f"Emitting heartbeat for {self.gui_id}")
self.client.connector.set(
MessageEndpoints.gui_heartbeat(self.gui_id),
messages.StatusMessage(name=self.gui_id, status=self.status, info={}),
@ -120,6 +124,7 @@ class BECWidgetsCLIServer:
)
def shutdown(self): # TODO not sure if needed when cleanup is done at level of BECConnector
logger.info(f"Shutting down server with gui_id: {self.gui_id}")
self.status = messages.BECStatus.IDLE
self._heartbeat_timer.stop()
self.emit_heartbeat()
@ -137,7 +142,8 @@ class SimpleFileLikeFromLogOutputFunc:
def flush(self):
lines, _, remaining = "".join(self._buffer).rpartition("\n")
self._log_func(lines)
if lines:
self._log_func(lines)
self._buffer = [remaining]
def close(self):
@ -155,12 +161,12 @@ def _start_server(gui_id: str, gui_class: Union[BECFigure, BECDockArea], config:
# if no config is provided, use the default config
service_config = ServiceConfig()
bec_logger.configure(
service_config.redis,
QtRedisConnector,
service_name="BECWidgetsCLIServer",
service_config=service_config.service_config,
)
# bec_logger.configure(
# service_config.redis,
# QtRedisConnector,
# service_name="BECWidgetsCLIServer",
# service_config=service_config.service_config,
# )
server = BECWidgetsCLIServer(gui_id=gui_id, config=service_config, gui_class=gui_class)
return server
@ -175,6 +181,12 @@ def main():
import bec_widgets
bec_logger.level = bec_logger.LOGLEVEL.DEBUG
if __name__ != "__main__":
# if not running as main, set the log level to critical
# pylint: disable=protected-access
bec_logger._stderr_log_level = bec_logger.LOGLEVEL.CRITICAL
parser = argparse.ArgumentParser(description="BEC Widgets CLI Server")
parser.add_argument("--id", type=str, help="The id of the server")
parser.add_argument(
@ -197,7 +209,7 @@ def main():
)
gui_class = BECFigure
with redirect_stdout(SimpleFileLikeFromLogOutputFunc(logger.debug)):
with redirect_stdout(SimpleFileLikeFromLogOutputFunc(logger.info)):
with redirect_stderr(SimpleFileLikeFromLogOutputFunc(logger.error)):
app = QApplication(sys.argv)
app.setApplicationName("BEC Figure")

View File

@ -16,7 +16,6 @@ class TicTacToe(QWidget): # pragma: no cover
super().__init__(parent)
self._state = DEFAULT_STATE
self._turn_number = 0
print("TicTac HERE !!!!!!")
def minimumSizeHint(self):
return QSize(200, 200)

View File

@ -6,7 +6,7 @@ import time
import uuid
from typing import Optional
import yaml
from bec_lib.logger import bec_logger
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
@ -17,6 +17,7 @@ from bec_widgets.qt_utils.error_popups import ErrorPopupUtility
from bec_widgets.qt_utils.error_popups import SafeSlot as pyqtSlot
from bec_widgets.utils.yaml_dialog import load_yaml, load_yaml_gui, save_yaml, save_yaml_gui
logger = bec_logger.logger
BECDispatcher = lazy_import_from("bec_widgets.utils.bec_dispatcher", ("BECDispatcher",))
@ -81,9 +82,9 @@ class BECConnector:
# the function depends on BECClient, and BECDispatcher
@pyqtSlot()
def terminate(client=self.client, dispatcher=self.bec_dispatcher):
print("Disconnecting", repr(dispatcher))
logger.info("Disconnecting", repr(dispatcher))
dispatcher.disconnect_all()
print("Shutting down BEC Client", repr(client))
logger.info("Shutting down BEC Client", repr(client))
client.shutdown()
BECConnector.EXIT_HANDLERS[self.client] = terminate
@ -93,7 +94,7 @@ class BECConnector:
self.config = config
self.config.widget_class = self.__class__.__name__
else:
print(
logger.debug(
f"No initial config found for {self.__class__.__name__}.\n"
f"Initializing with default config."
)

View File

@ -6,11 +6,14 @@ from typing import TYPE_CHECKING, Union
import redis
from bec_lib.client import BECClient
from bec_lib.logger import bec_logger
from bec_lib.redis_connector import MessageObject, RedisConnector
from bec_lib.service_config import ServiceConfig
from qtpy.QtCore import QObject
from qtpy.QtCore import Signal as pyqtSignal
logger = bec_logger.logger
if TYPE_CHECKING:
from bec_lib.endpoints import EndpointInfo
@ -65,11 +68,6 @@ class QtRedisConnector(RedisConnector):
cb(msg.content, msg.metadata)
class BECClientWithoutLoggerInit(BECClient):
def _initialize_logger(self):
return
class BECDispatcher:
"""Utility class to keep track of slots connected to a particular redis connector"""
@ -94,24 +92,22 @@ class BECDispatcher:
if not isinstance(config, ServiceConfig):
# config is supposed to be a path
config = ServiceConfig(config)
self.client = BECClientWithoutLoggerInit(
config=config, connector_cls=QtRedisConnector
) # , forced=True)
else:
self.client = BECClientWithoutLoggerInit(
connector_cls=QtRedisConnector
) # , forced=True)
self.client = BECClient(
config=config, connector_cls=QtRedisConnector, name="BECWidgets"
)
else:
if self.client.started:
# have to reinitialize client to use proper connector
logger.info("Shutting down BECClient to switch to QtRedisConnector")
self.client.shutdown()
self.client._BECClient__init_params["connector_cls"] = QtRedisConnector
try:
self.client.start()
except redis.exceptions.ConnectionError:
print("Could not connect to Redis, skipping start of BECClient.")
logger.warning("Could not connect to Redis, skipping start of BECClient.")
logger.success("Initialized BECDispatcher")
self._initialized = True
@classmethod

View File

@ -1,12 +1,15 @@
from __future__ import annotations
import darkdetect
from bec_lib.logger import bec_logger
from qtpy.QtCore import Slot
from qtpy.QtWidgets import QApplication, QWidget
from bec_widgets.utils.bec_connector import BECConnector, ConnectionConfig
from bec_widgets.utils.colors import set_theme
logger = bec_logger.logger
class BECWidget(BECConnector):
"""Mixin class for all BEC widgets, to handle cleanup"""
@ -54,6 +57,7 @@ class BECWidget(BECConnector):
set_theme("light")
if theme_update:
logger.debug(f"Subscribing to theme updates for {self.__class__.__name__}")
self._connect_to_theme_change()
def _connect_to_theme_change(self):

View File

@ -2,6 +2,7 @@ from __future__ import annotations
from typing import TYPE_CHECKING
from bec_lib.logger import bec_logger
from qtpy.QtCore import QMimeData, Qt
from qtpy.QtGui import QDrag
from qtpy.QtWidgets import QHBoxLayout, QLabel, QWidget
@ -9,6 +10,8 @@ from qtpy.QtWidgets import QHBoxLayout, QLabel, QWidget
if TYPE_CHECKING:
from qtpy.QtGui import QMouseEvent
logger = bec_logger.logger
class DeviceItem(QWidget):
def __init__(self, device: str) -> None:
@ -37,7 +40,7 @@ class DeviceItem(QWidget):
drag.exec_(Qt.MoveAction)
def mouseDoubleClickEvent(self, event: QMouseEvent) -> None:
print("Double Clicked")
logger.debug("Double Clicked")
# TODO: Implement double click action for opening the device properties dialog
return super().mouseDoubleClickEvent(event)

View File

@ -7,6 +7,7 @@ from typing import Literal, Optional
import numpy as np
import pyqtgraph as pg
from bec_lib.logger import bec_logger
from pydantic import Field, ValidationError, field_validator
from qtpy.QtCore import Signal as pyqtSignal
from qtpy.QtWidgets import QWidget
@ -20,6 +21,8 @@ from bec_widgets.widgets.figure.plots.motor_map.motor_map import BECMotorMap, Mo
from bec_widgets.widgets.figure.plots.plot_base import BECPlotBase, SubplotConfig
from bec_widgets.widgets.figure.plots.waveform.waveform import BECWaveform, Waveform1DConfig
logger = bec_logger.logger
class FigureConfig(ConnectionConfig):
"""Configuration for BECFigure. Inheriting from ConnectionConfig widget_class and gui_id"""
@ -179,7 +182,7 @@ class BECFigure(BECWidget, pg.GraphicsLayoutWidget):
try:
config = FigureConfig(**config)
except ValidationError as e:
print(f"Error in applying config: {e}")
logger.error(f"Error in applying config: {e}")
return
self.config = config

View File

@ -5,6 +5,7 @@ from typing import Any, Literal, Optional
import numpy as np
from bec_lib.endpoints import MessageEndpoints
from bec_lib.logger import bec_logger
from pydantic import BaseModel, Field, ValidationError
from qtpy.QtCore import QThread
from qtpy.QtWidgets import QWidget
@ -19,6 +20,8 @@ from bec_widgets.widgets.figure.plots.image.image_processor import (
)
from bec_widgets.widgets.figure.plots.plot_base import BECPlotBase, SubplotConfig
logger = bec_logger.logger
class ImageConfig(SubplotConfig):
images: dict[str, ImageItemConfig] = Field(
@ -130,7 +133,7 @@ class BECImageShow(BECPlotBase):
try:
config = ImageConfig(**config)
except ValidationError as e:
print(f"Validation error when applying config to BECImageShow: {e}")
logger.error(f"Validation error when applying config to BECImageShow: {e}")
return
self.config = config
self.plot_item.clear()

View File

@ -4,6 +4,7 @@ from typing import TYPE_CHECKING, Literal, Optional
import numpy as np
import pyqtgraph as pg
from bec_lib.logger import bec_logger
from pydantic import Field
from bec_widgets.utils import BECConnector, ConnectionConfig
@ -12,6 +13,8 @@ from bec_widgets.widgets.figure.plots.image.image_processor import ImageStats, P
if TYPE_CHECKING:
from bec_widgets.widgets.figure.plots.image.image import BECImageShow
logger = bec_logger.logger
class ImageItemConfig(ConnectionConfig):
parent_id: Optional[str] = Field(None, description="The parent plot of the image.")
@ -133,7 +136,7 @@ class BECImageItem(BECConnector, pg.ImageItem):
if key in method_map:
method_map[key](value)
else:
print(f"Warning: '{key}' is not a recognized property.")
logger.warning(f"Warning: '{key}' is not a recognized property.")
def set_fft(self, enable: bool = False):
"""

View File

@ -6,6 +6,7 @@ from typing import Optional, Union
import numpy as np
import pyqtgraph as pg
from bec_lib.endpoints import MessageEndpoints
from bec_lib.logger import bec_logger
from pydantic import Field, ValidationError, field_validator
from pydantic_core import PydanticCustomError
from qtpy import QtCore, QtGui
@ -17,6 +18,8 @@ from bec_widgets.utils import Colors, EntryValidator
from bec_widgets.widgets.figure.plots.plot_base import BECPlotBase, SubplotConfig
from bec_widgets.widgets.figure.plots.waveform.waveform import Signal, SignalData
logger = bec_logger.logger
class MotorMapConfig(SubplotConfig):
signals: Optional[Signal] = Field(None, description="Signals of the motor map")
@ -101,7 +104,7 @@ class BECMotorMap(BECPlotBase):
try:
config = MotorMapConfig(**config)
except ValidationError as e:
print(f"Error in applying config: {e}")
logger.error(f"Error in applying config: {e}")
return
self.config = config
@ -440,7 +443,7 @@ class BECMotorMap(BECPlotBase):
return limits
except AttributeError: # TODO maybe not needed, if no limits it returns [0,0]
# If the motor doesn't have a 'limits' attribute, return a default value or raise a custom exception
print(f"The device '{motor}' does not have defined limits.")
logger.error(f"The device '{motor}' does not have defined limits.")
return None
@Slot()

View File

@ -4,6 +4,7 @@ from typing import Literal, Optional
import bec_qthemes
import pyqtgraph as pg
from bec_lib.logger import bec_logger
from pydantic import BaseModel, Field
from qtpy.QtCore import Signal, Slot
from qtpy.QtWidgets import QApplication, QWidget
@ -11,6 +12,8 @@ from qtpy.QtWidgets import QApplication, QWidget
from bec_widgets.utils import BECConnector, ConnectionConfig
from bec_widgets.utils.crosshair import Crosshair
logger = bec_logger.logger
class AxisConfig(BaseModel):
title: Optional[str] = Field(None, description="The title of the axes.")
@ -164,7 +167,7 @@ class BECPlotBase(BECConnector, pg.GraphicsLayout):
if key in method_map:
method_map[key](value)
else:
print(f"Warning: '{key}' is not a recognized property.")
logger.warning(f"Warning: '{key}' is not a recognized property.")
def apply_axis_config(self):
"""Apply the axis configuration to the plot widget."""

View File

@ -8,6 +8,7 @@ import pyqtgraph as pg
from bec_lib import messages
from bec_lib.device import ReadoutPriority
from bec_lib.endpoints import MessageEndpoints
from bec_lib.logger import bec_logger
from pydantic import Field, ValidationError, field_validator
from pyqtgraph.exporters import MatplotlibExporter
from qtpy.QtCore import Signal as pyqtSignal
@ -23,6 +24,8 @@ from bec_widgets.widgets.figure.plots.waveform.waveform_curve import (
SignalData,
)
logger = bec_logger.logger
class Waveform1DConfig(SubplotConfig):
color_palette: Optional[str] = Field(
@ -139,7 +142,7 @@ class BECWaveform(BECPlotBase):
try:
config = Waveform1DConfig(**config)
except ValidationError as e:
print(f"Validation error when applying config to BECWaveform1D: {e}")
logger.error(f"Validation error when applying config to BECWaveform1D: {e}")
return
self.config = config
@ -553,7 +556,7 @@ class BECWaveform(BECPlotBase):
format="HEX",
)[len(self.plot_item.curves)]
)
print(f"Color: {color}")
logger.info(f"Color: {color}")
# Create curve by config
curve_config = CurveConfig(
@ -1291,7 +1294,7 @@ class BECWaveform(BECPlotBase):
try:
self.scan_id = self.queue.scan_storage.storage[scan_index].scan_id
except IndexError:
print(f"Scan index {scan_index} out of range.")
logger.error(f"Scan index {scan_index} out of range.")
return
elif scan_id is not None:
self.scan_id = scan_id
@ -1317,7 +1320,7 @@ class BECWaveform(BECPlotBase):
except ImportError:
pd = None
if output == "pandas":
print(
logger.warning(
"Pandas is not installed. "
"Please install pandas using 'pip install pandas'."
"Output will be dictionary instead."

View File

@ -4,8 +4,8 @@ from typing import TYPE_CHECKING, Any, Literal, Optional
import numpy as np
import pyqtgraph as pg
from bec_lib.logger import bec_logger
from pydantic import BaseModel, Field, field_validator
from pydantic_core import PydanticCustomError
from qtpy import QtCore
from bec_widgets.utils import BECConnector, Colors, ConnectionConfig
@ -13,6 +13,8 @@ from bec_widgets.utils import BECConnector, Colors, ConnectionConfig
if TYPE_CHECKING:
from bec_widgets.widgets.figure.plots.waveform import BECWaveform1D
logger = bec_logger.logger
class SignalData(BaseModel):
"""The data configuration of a signal in the 1D waveform widget for x and y axis."""
@ -177,7 +179,7 @@ class BECCurve(BECConnector, pg.PlotDataItem):
if key in method_map:
method_map[key](value)
else:
print(f"Warning: '{key}' is not a recognized property.")
logger.warning(f"Warning: '{key}' is not a recognized property.")
def set_color(self, color: str, symbol_color: Optional[str] = None):
"""

View File

@ -4,6 +4,7 @@ from typing import Literal, Optional
import pyqtgraph as pg
from bec_lib.endpoints import MessageEndpoints
from bec_lib.logger import bec_logger
from pydantic import Field, field_validator
from pydantic_core import PydanticCustomError
from qtpy import QtCore, QtGui
@ -14,6 +15,8 @@ from bec_widgets.utils import Colors, ConnectionConfig, EntryValidator
from bec_widgets.utils.bec_widget import BECWidget
from bec_widgets.widgets.ring_progress_bar.ring import Ring, RingConfig
logger = bec_logger.logger
class RingProgressBarConfig(ConnectionConfig):
color_map: Optional[str] = Field(
@ -38,7 +41,7 @@ class RingProgressBarConfig(ConnectionConfig):
min_number_of_bars = values.data.get("min_number_of_bars", None)
max_number_of_bars = values.data.get("max_number_of_bars", None)
if min_number_of_bars is not None and max_number_of_bars is not None:
print(
logger.info(
f"Number of bars adjusted to be between defined min:{min_number_of_bars} and max:{max_number_of_bars} number of bars."
)
v = max(min_number_of_bars, min(v, max_number_of_bars))
@ -318,7 +321,7 @@ class RingProgressBar(BECWidget, QWidget):
ring = self._find_ring_by_index(ring_index)
if isinstance(values, list):
values = values[0]
print(
logger.warning(
f"Warning: Only a single value can be set for a single progress bar. Using the first value in the list {values}"
)
ring.set_value(values)
@ -380,7 +383,7 @@ class RingProgressBar(BECWidget, QWidget):
ring = self._find_ring_by_index(bar_index)
if isinstance(widths, list):
widths = widths[0]
print(
logger.warning(
f"Warning: Only a single line width can be set for a single progress bar. Using the first value in the list {widths}"
)
ring.set_line_width(widths)
@ -487,7 +490,7 @@ class RingProgressBar(BECWidget, QWidget):
for index, device in enumerate(devices):
self._hook_readback(index, device, start[index], end[index])
else:
print(f"{instruction_type} not supported yet.")
logger.error(f"{instruction_type} not supported yet.")
# elif instruction_type == "device_progress":
# print("hook device_progress")
@ -609,7 +612,7 @@ class RingProgressBar(BECWidget, QWidget):
Calculate the minimum size of the widget.
"""
if not self.config.rings:
print("no rings to get size from setting size to 10x10")
logger.warning("no rings to get size from setting size to 10x10")
return QSize(10, 10)
ring_widths = [self.config.rings[i].line_width for i in range(self.config.num_bars)]
total_width = sum(ring_widths) + self.config.gap * (self.config.num_bars - 1)

View File

@ -1,5 +1,6 @@
from typing import Literal
from bec_lib.logger import bec_logger
from qtpy.QtCore import Qt
from qtpy.QtWidgets import (
QCheckBox,
@ -18,6 +19,8 @@ from qtpy.QtWidgets import (
from bec_widgets.utils.widget_io import WidgetIO
from bec_widgets.widgets.device_line_edit.device_line_edit import DeviceLineEdit
logger = bec_logger.logger
class ScanArgType:
DEVICE = "device"
@ -191,7 +194,9 @@ class ScanGroupBox(QGroupBox):
default = item.get("default", None)
widget = self.WIDGET_HANDLER.get(item["type"], None)
if widget is None:
print(f"Unsupported annotation '{item['type']}' for parameter '{item['name']}'")
logger.error(
f"Unsupported annotation '{item['type']}' for parameter '{item['name']}'"
)
continue
if default == "_empty":
default = None

View File

@ -5,6 +5,7 @@ from typing import Literal
import numpy as np
import pyqtgraph as pg
from bec_lib.logger import bec_logger
from qtpy.QtCore import Signal
from qtpy.QtWidgets import QVBoxLayout, QWidget
@ -26,6 +27,8 @@ try:
except ImportError:
pd = None
logger = bec_logger.logger
class BECWaveformWidget(BECWidget, QWidget):
ICON_NAME = "show_chart"
@ -425,7 +428,7 @@ class BECWaveformWidget(BECWidget, QWidget):
except ImportError:
pd = None
if output == "pandas":
print(
logger.warning(
"Pandas is not installed. "
"Please install pandas using 'pip install pandas'."
"Output will be dictionary instead."

View File

@ -71,6 +71,6 @@ def test_client_utils_passes_client_config_to_server(bec_dispatcher):
mock_start_plot.return_value = [mock.MagicMock(), mock.MagicMock()]
mixin.show()
mock_start_plot.assert_called_once_with(
"gui_id", BECGuiClientMixin, mixin._client._service_config.config
"gui_id", BECGuiClientMixin, mixin._client._service_config.config, logger=mock.ANY
)
mock_start_update.assert_called_once()