Dispatching requests
Transporting requests to their destined handlers.
Buses
The Bus
protocol wraps a command dispatcher and message bus
implementation. The bus routes requests to their subscribed handlers via a
composable chain of middleware.
Subscriptions
A bus must be able to find the handlers for a request to dispatch it. Subscriptions hold the connection from a handler to a request.
The Registry
manages subscriptions, and provides them via the
HandlerLocator
protocol.
Subscribe a handler to a request via a manual definition or using a decorator.
import banshee
registry = banshee.Registry()
registry.subscribe(do_greeting, to=GreetCommand)
# or via a decorator
@registry.subscribe_to(GreetCommand)
async def do_greeting(command: GreetCommand) -> None:
print(f"Hello {command.name}!")
Building a bus
You use the Builder
class to construct a bus instance. Builder is an
example of the builder pattern and uses a fluent interface to define a bus.
import banshee
bus = (
banshee.Builder()
.with_locator(registry)
.build()
)
Sending a request
Once you have registered your handlers, you can dispatch requests to them via the bus.
await bus.handle(GreetCommand(name="Joe"))
Querying
You can get a result back from a handler by sending a query.
@dataclasses.dataclass(freeze=True)
class GetUserQuery:
user_id: int
@registry.subscribe_to(GetUserQuery)
async def do_greeting(query: GetUserQuery) -> User:
return user_store.get(query.user_id)
user = await bus.query(GetUserQuery(user_id=1))
Reference
- class banshee.Builder(middleware=<factory>, locator=None, factory=None)
Bases:
object
Builder.
Provides a chained interface to construct an instance of {class}`banshee.Bus`.
- Parameters:
middleware (tuple[Middleware, ...]) –
locator (HandlerLocator | None) –
factory (HandlerFactory | None) –
- build()
Build.
Assemble the message bus instance
- Returns:
a message bus instance
- Raises:
ConfigurationError – when bus is incorrectly configured
- Return type:
- with_factory(factory)
With factory.
Set factory for the message bus.
- Parameters:
factory (HandlerFactory) – handler factory instance
- Returns:
builder instance with factory
- Return type:
- with_locator(locator)
With locator.
Set locator for the message bus.
- Parameters:
locator (HandlerLocator) – handler locator instance
- Returns:
builder instance with locator
- Return type:
- with_middleware(middleware)
With middleware.
Add a middleware to the message bus.
- Parameters:
middleware (Middleware) – middleware instance
- Returns:
builder instance with middleware added
- Return type:
- class banshee.Bus(*args, **kwargs)
Bases:
Protocol
Bus protocol.
An command/event/query bus for dispatching requests to handlers.
- async query(query, contexts=None)
Query.
Send a query to the message bus and return the result.
- Parameters:
- Returns:
the result of the query
- Raises:
ConfigurationError – query does not map to exactly one handler
- Return type:
- class banshee.HandlerLocator(*args, **kwargs)
Bases:
Protocol
Handler locator protocol.
Locates handlers that can process the messages request.
- abstract subscribers_for(message)
Get subscribers for message.
Returns references to handlers for the passed messages request.
- Parameters:
message (Message[T]) – message of request
- Returns:
list of references to handlers for the message
- Return type:
- class banshee.HandlerReference(name, handler)
Bases:
Generic
[T
]Handler reference.
A reference to a type or callable, including a unique name for said type or callable, that when passed to a
HandlerFactory
will result in an instantiatedHandler
.
- class banshee.Registry
Bases:
HandlerLocator
Registry.
Provides a means to register and lookup objects.
- subscribe(handler, to, name=None)
Subscribe.
Add a subscription for a function or class to a request class.
When no name is provided, then the registry will try and infer a unique name based on the module and name of the decorated function or class.
- subscribe_to(to, name=None)
Subscribe to.
A decorator to subscribe the decorated function or class to requests of the specified type.
When no name is provided, then the registry will try and infer a unique name based on the module and name of the decorated function or class.
- subscribers_for(message)
Get subscribers for message.
Returns references to handlers for the passed messages request.
- Parameters:
message (Message[T]) – message of request
- Returns:
list of references to handlers for the message
- Return type: