diff --git a/bec_lib/bec_lib/messaging_services.py b/bec_lib/bec_lib/messaging_services.py index 2711701c5..50138a76c 100644 --- a/bec_lib/bec_lib/messaging_services.py +++ b/bec_lib/bec_lib/messaging_services.py @@ -36,12 +36,13 @@ def __init__(self, service: MessagingService, scope: str | list[str] | None = No self._scope = scope self._content = [] - def add_text(self, text: str) -> Self: + def add_text(self, text: str, **kwargs) -> Self: """ Add text to the message object. Args: text (str): The text to add. + **kwargs: Additional keyword arguments for specific messaging services. Returns: MessageObject: The updated message object. @@ -268,6 +269,43 @@ class SciLogMessageServiceObject(MessageServiceObject): A class representing a message object for the SciLog messaging service. """ + def add_text( + self, + text: str, + bold: bool = False, + italic: bool = False, + color: str | None = None, + **kwargs, + ) -> Self: + """ + Add text to the SciLog message with optional inline HTML formatting. + + When any formatting option is supplied the text is wrapped in a ``

`` + paragraph so SciLog renders it correctly. + + Args: + text: The text content. + bold: Wrap the text in ````. + italic: Wrap the text in ````. + color: Highlight colour using SciLog's pen marks (e.g. ``"red"``, + ``"yellow"``, ``"green"``, ``"blue"``, ``"pink"``). + + Returns: + SciLogMessageServiceObject: The updated message object. + + Examples: + >>> msg.add_text("Checks failed", bold=True, color="red") + """ + if bold or italic or color: + if bold: + text = f"{text}" + if italic: + text = f"{text}" + if color: + text = f'{text}' + text = f"

{text}

" + return super().add_text(text) + def add_tags(self, tags: str | list[str]) -> Self: """ Add tags to the SciLog message object. diff --git a/bec_lib/tests/test_messaging_service.py b/bec_lib/tests/test_messaging_service.py index f880a1a2d..f59643de5 100644 --- a/bec_lib/tests/test_messaging_service.py +++ b/bec_lib/tests/test_messaging_service.py @@ -469,3 +469,37 @@ def test_scilog_message_add_duplicate_tags(scilog_message, connected_connector): assert isinstance(tags_part, messages.MessagingServiceTagsContent) # The final tags should include all unique tags without duplicates assert sorted(tags_part.tags) == sorted(["bec", "default_tag", "additional_tag"]) + + +def test_scilog_add_text_no_formatting(scilog_message): + scilog_message.add_text("plain") + assert scilog_message._content[0].content == "plain" + + +def test_scilog_add_text_bold(scilog_message): + scilog_message.add_text("hello", bold=True) + assert scilog_message._content[0].content == "

hello

" + + +def test_scilog_add_text_italic(scilog_message): + scilog_message.add_text("hello", italic=True) + assert scilog_message._content[0].content == "

hello

" + + +def test_scilog_add_text_color(scilog_message): + scilog_message.add_text("warn", color="yellow") + assert scilog_message._content[0].content == '

warn

' + + +def test_scilog_add_text_bold_and_color(scilog_message, connected_connector): + """bold + color produces the expected nested HTML and round-trips through redis.""" + scilog_message.add_text("Beamline checks failed", bold=True, color="red") + scilog_message.send() + + out = connected_connector.xread(MessageEndpoints.message_service_queue(), from_start=True) + text_part = out[0]["data"].message[0] + assert isinstance(text_part, messages.MessagingServiceTextContent) + assert ( + text_part.content + == '

Beamline checks failed

' + )