Coverage for /Users/eugene/Development/robotnikmq/robotnikmq/topic.py: 100%
21 statements
« prev ^ index » next coverage.py v7.3.4, created at 2023-12-26 23:29 -0500
« prev ^ index » next coverage.py v7.3.4, created at 2023-12-26 23:29 -0500
1import json
2from typing import Optional
4from pika.exceptions import AMQPError
5from pika.exchange_type import ExchangeType
6from tenacity import retry, retry_if_exception_type, wait_exponential
7from typeguard import typechecked
9from robotnikmq.config import RobotnikConfig
10from robotnikmq.core import Robotnik, Message
13class Topic(Robotnik):
14 """The Topic is one of two key elements of the Publish/Subscribe workflow with RobotnikMQ.
15 Once configured, a topic is able to broadcast messages to any Subscribers on a given exchange
16 and routing key combination.
17 """
18 @typechecked
19 def __init__(
20 self,
21 exchange: str,
22 config: Optional[RobotnikConfig] = None,
23 ):
24 super().__init__(config=config)
25 self.exchange = exchange
26 self.channel.exchange_declare(
27 exchange=self.exchange, exchange_type=ExchangeType.topic, auto_delete=True
28 )
30 @retry(
31 retry=retry_if_exception_type((AMQPError, OSError)),
32 wait=wait_exponential(multiplier=1, min=3, max=30),
33 reraise=True
34 )
35 @typechecked
36 def broadcast(
37 self,
38 msg: Message,
39 routing_key: Optional[str] = None
40 ) -> None:
41 """Broadcasts a message with an optional routing key.
43 Args:
44 msg (Message): The message to be broadcast.
45 routing_key (Optional[str], optional): Routing key used to broadcast the message.
46 Defaults to an empty string.
47 on_msg_error (AMQPErrorCallback, optional): _description_. Defaults to None.
48 """
49 msg = msg.with_routing_key(routing_key or msg.routing_key or "")
50 self.log.info("Broadcasting message (routing-key: [{}]):\n{}",
51 msg.routing_key, json.dumps(msg.to_dict(), indent=4))
52 self.channel.basic_publish(
53 exchange=self.exchange,
54 routing_key=msg.routing_key,
55 body=json.dumps(msg.to_dict()),
56 )
57 self.log.success("Broadcast:\n{}", json.dumps(msg.to_dict(), indent=4))