Events

Events are a major part of how Watson wires together your application. You can hook into the events and register your own event listeners by modifying your application configuration.

The event dispatcher holds a record of all listeners and the their associated priority, number of executions, and the event name that they are to be executed on.

Note

The basic flow for the event system within Watson is the following:

Create dispatcher > Add listeners > Trigger event > Return results from triggered listeners

The anatomy of an Event

An event is used to pass around data within an application without introducing a tight coupling between objects. A basic event contains the following:

A name
The name of the event that will trigger listener callbacks
A target
What triggered the event
A set of parameters
Data sent through with the event

When an event is triggered from an event dispatcher, all listeners that are listening for a particular event name will be triggered and their responses returned.

Inbuilt events

The lifecycle of a Watson application is maintained by 5 different events defined in watson.framework.events:

event.framework.init
Triggered when the application is started
event.framework.route.match
Triggered when the application attempts to route a request and returns the matches
event.framework.dispatch.execute
Triggered when the controller is executed and returns the response
event.framework.render.view
Triggered when the controller response is processed and the view is rendered
event.framework.exception
Triggered when any exception occurs within the application and the executes prior to the render view to generate any 400/500 error pages

These events are triggered by the shared_event_dispatcher which is instantiated from the applications IocContainer.

Creating and registering your own event listeners

By default several listeners are defined within the watson.framework.config module, however additional listeners can be added to these events, and even prevent the default listeners from being triggered.

Let’s assume that we want to add a new listener to the watson.framework.events.INIT event. First lets add a new events key to the applications configuration module. Replace app_name with the applications name.

app_name/config/config.py

from watson.framework import events

events = {
}

Note

Whatever defined in here will be appended to Watsons default configuration.

Next, we’ll need to create a listener, which just needs to be a callable object. As the listener is going to be retrieved from the IocContainer, it is useful to subclass watson.di.ContainerAware so that the container will be injected automatically. The triggered listener is passed a single event as the argument, so make sure that you allow for that.

app_name/listeners.py

from watson.di import ContainerAware
from watson.framework import listeners

class MyFirstListener(listeners.Base, ContainerAware):
    def __call__(self, event):
        # we'll perform something based on the event and target here
        pass

Finally we’ll need to register the listener with the event dispatcher. Each listener needs to be added as a tuple, which takes the following arguments: (object, int priority, boolean once_only). If no priority is specified a default priority of 1 will be given. The highest priority will be executed first. If only_once is not specified then it will default to False.

app_name/config/config.py

events = {
    events.INIT: [
        ('app_name.listeners.MyFirstListener', 2, True)
    ]
}

Now once your application is initialized your event will be triggered.