Source code for bus_ride.handler

from abc import ABC, abstractmethod
from typing import ClassVar

from attrs import define, field

from . import MessageBusConfigurationError
from .command import Command
from .event import Event
from .returnmessage import ReturnMessage

type HandlerReturnType = list[Command | ReturnMessage]


[docs] @define class Handler(ABC): """ Abstract base class for handling one or more :py:class:`~bus_ride.event.Event`. Event handlers should do as little as possible, such as send a quick notification, log an action, or issue Command(s). If an Event implies anything significant needs to be done in response, the Handler should return :py:class:`~bus_ride.command.Command` object(s). We can't enforce this guideline for you, but recommend you follow it. Your handler may return a list containing :py:class:`~bus_ride.command.Command` and/or :py:class:`~bus_ride.returnmessage.ReturnMessage` objects. If one or more :py:class:`~bus_ride.returnmessage.ReturnMessage` are returned, your application should do something with them. .. note:: Event handlers are located by searching through all subclasses of ``Handler``, to find Handler(s) that accept the Event. They are cached once located. If any of your Handlers are not being used when they should be, make sure they are imported when your application starts up. Usually, importing them in an ``__init__.py`` file or keeping them in the same file with their ``Event`` will fix it. """ event: Event = field() handles_events: ClassVar[list[type[Event]]] """ A list of the :py:class:`~bus_ride.event.Event` class(es) this ``Handler`` should respond to. """ def __attrs_post_init__(self): # pragma: no cover if not self.handles_events: msg = f"Handler {self.__class__.__name__} must define handles_events." raise MessageBusConfigurationError(msg)
[docs] @abstractmethod def handle_event(self) -> HandlerReturnType: # pragma: no cover """ Your implementation of a response to ``self.event``. """ raise NotImplementedError
[docs] @classmethod def handles_event(cls, event: Event) -> bool: # pragma: no cover """ Determines whether this handler should respond to ``event``. """ return type(event) in cls.handles_events
type HandlerType = type[Handler]