messaging¶
Messaging framework foundations.
-
class
frequent.messaging.
HandlerRegistry
[source]¶ Bases:
collections.abc.Mapping
A registry containing mappings of message type to handler(s).
Examples
To add mappings:
>>> registry = HandlerRegistry() >>> msg_bus = MessageBus() >>> my_handler = MyMessageHandler(msg_bus) >>> registry.add(MyMessage, my_handler) >>> registry <HandlerRegistry mappings={ 'MyMessage': [1 handler], }>
-
add
(msg_cls: Type[frequent.messaging.Message], handler: Union[Callable[[Message], None], MessageHandler], *handlers) → None[source]¶ Adds message handler(s) for the specified message type.
- Parameters
msg_cls (
type
ofMessage
) – The message class to add handler mappings for.handler (
MessageHandler
orCallable
) – The message handler to map to the givenmsg_cls
type.handlers (optional) – Additional message handler(s) to map to the given
msg_cls
type.
-
get
(key: Type[frequent.messaging.Message], default: Any = None) → Sequence[Union[Callable[[frequent.messaging.Message], None], frequent.messaging.MessageHandler]][source]¶ Gets the message handler(s) associated with the given type.
- Parameters
key (
type
ofMessage
) – The message type to get the associated handlers for.default (optional) – The value to return if no associated handlers are found.
- Returns
The message handlers found (if any) or the
default
value given if no message handlers are found.- Return type
Sequence
ofCallable
orobject
-
remove
(msg_cls: Type[frequent.messaging.Message]) → Sequence[Union[Callable[[frequent.messaging.Message], None], frequent.messaging.MessageHandler]][source]¶ Removes all mappings for the specified message type.
- Parameters
msg_cls (
type
ofMessage
) – The message type to remove all handler mappings for.- Returns
The message handlers which were mapped to the specified
msg_cls
type.- Return type
Sequence
ofCallable
- Raises
NoHandlersFoundException – If no handlers were mapped to the specified
msg_cls
type.
-
-
class
frequent.messaging.
Message
[source]¶ Bases:
abc.ABC
Base class for all message objects.
-
id
¶ A unique universal identifier for this message.
- Type
UUID
Example
Derived message classes can be created from this class, though the
message
decorator is simpler to use. To create a message class directly from this base class:from dataclasses import dataclass @dataclass class DirectMessage(Message): to: str sender: str text: str
>>> msg = DirectMessage('Liz', 'Doug', 'Hello!') >>> msg DirectMessage(to='Liz', sender='Doug', text='Hello!') >>> msg.id UUID('5a47c192-a50b-11e9-bc30-a434d9ba8632')
See also
-
id
= UUID('6236b68c-b6f5-11e9-a651-0242ac110002')
-
-
class
frequent.messaging.
MessageBus
(registry: Optional[frequent.messaging.HandlerRegistry] = None)[source]¶ Bases:
object
Message bus for routing messages to the appropriate handlers.
- Parameters
registry (HandlerRegistry, optional) – The initial message type to handler mapping registry to use.
-
handle
(msg: frequent.messaging.Message) → None[source]¶ Handles the given message.
- Parameters
msg (Message) – The message object to handle.
- Raises
NoHandlersFoundException – This exception will be raised if no message handlers were registered for the given type of message.
-
property
registry
¶ The handler mapping registry in use.
- Type
-
class
frequent.messaging.
MessageHandler
(bus: frequent.messaging.MessageBus)[source]¶ Bases:
object
Message handling base class.
-
property
bus
¶ The message bus to use for subsequent messages.
- Type
-
abstract
handle
(msg: frequent.messaging.Message, successor: Union[Callable[[Message], None], MessageHandler, None] = None) → None[source]¶ Handles the given message object.
- Parameters
msg (Message) – The message object to handle.
successor (
MessageHandler
orCallable
, optional) – The next handler in the chain.
-
property
-
exception
frequent.messaging.
MessagingException
[source]¶ Bases:
Exception
Messaging framework base exception.
-
exception
frequent.messaging.
NoHandlersFoundException
(msg_cls: Type[frequent.messaging.Message])[source]¶ Bases:
frequent.messaging.MessagingException
Exception thrown if no message handlers were found.
- Parameters
msg_cls (
type
ofMessage
) – The message type which caused this exception to be thrown.
-
frequent.messaging.
chain
(*handlers) → Union[Callable[[frequent.messaging.Message], None], frequent.messaging.MessageHandler][source]¶ Chains multiple handlers together.
- Parameters
handlers (
MessageHandler
orCallable
) – The handlers to chain together, with each being passed the next handler via thesuccessor
keyword-argument.- Returns
The chained callable to use for message handling.
- Return type
Callable
Examples
To chain together two handlers into one:
>>> class MessageIdLogger(MessageHandler): ... def handle(self, msg, successor=None): ... # Print our message's ID ... print(msg.id) ... # ... then call the next handler. ... return successor(msg) ... >>> def my_next_handler(msg): ... if msg.code == 42: ... print('The answer!') ... else: ... print('Not the answer...') ... return >>> chained_handler = chain(MessageIdLogger(), my_next_handler) >>> ans_msg = MyMessage(42) >>> not_ans_msg = MyMessage(41) >>> chained_handler(answer_msg) 5a47c192-a50b-11e9-bc30-a434d9ba8632 The answer! >>> chained_handler(not_ans_msg) 9a47c651-a52b-11f9-bc80-a484d9ba8633 Not the answer
-
frequent.messaging.
convert_to_message
(cls: type, target_cls: Type[frequent.messaging.Message]) → Type[frequent.messaging.Message][source]¶ Converts the given cls to the specified
Message
class.User’s should prefer to use the
message
decorator as it’s easier to use and acts purely as a pass-through to this function. This function is provided to allow users to create decorators/functions to convert classes to their own customMessage
subclasses.
-
frequent.messaging.
message
(cls: type) → Type[frequent.messaging.Message][source]¶ Decorator for easily creating new
Message
sub-classes.- Parameters
cls (type) – The class to convert to a
Message
subclass.- Returns
The new class, converted to a subclass of
Message
.- Return type
type
ofMessage
Example
To create a new
Message
class using this decorator:@message class MyMessage: target: str value: int
Then new instances are created just like named tuples:
>>> msg = MyMessage('calc_func', 42) >>> msg <MyMessage target='calc_func' value=42>
See also