Skip to main content

Event sourcing and handling

Project description

django-spark - Event sourcing and handling

.. image::

Version |release|

This is not supposed to be real documentation; it's more a reminder for

The idea is that there are event sources and event handlers. Event
sources may create a stream of ``spark.api.Event`` instances, where each
event must have a ``group`` and a ``key``. Additional data may be added
to the ``Event`` as well. Keys are globally unique -- events with the
same key are still only processed exactly once. Groups are used to
determine which handlers handle a certain event.

Event handlers are functions which are called once per
``spark.api.Event`` instance if the event's group matches the event
handler's regex.

Some usage example code

Given a challenge, create events for the challenge (the specifics do not

.. code-block:: python

from datetime import date
from spark import api

def events_from_challenge(challenge):
if not challenge.is_active:

yield {
"group": 'challenge_created',
"key": 'challenge_created_%s' %,
"context": {"challenge": challenge},

if ( - challenge.start_date).days > 2:
if challenge.donations.count() < 2:
yield {
"group": 'challenge_inactivity_2d',
"key": 'challenge_inactivity_2d_%s' %,
"context": {"challenge": challenge},

if (challenge.end_date - <= 2:
yield {
"group": 'challenge_ends_2d',
"key": 'challenge_ends_2d_%s' %,
"context": {"challenge": challenge},

if challenge.end_date <
yield {
"group": 'challenge_ended',
"key": 'challenge_ended_%s' %,
"context": {"challenge": challenge},

Send mails related to challenges (uses django-authlib's

.. code-block:: python

from import render_to_mail

def send_challenge_mails(event):
challenge = event["context"]["challenge"]
# Different mail text per event group:
"challenges/mails/%s" % event["group"],
"challenge": challenge,

Register the handlers:

.. code-block:: python

class ChallengesConfig(AppConfig):
def ready(self):
# Prevent circular imports:
from spark import api


Challenge = self.get_model('Challenge')

# All this does right now is register a post_save signal
# handler which runs the challenge instance through
# events_from_challenge:

Now, events are generated and handled directly in process.
Alternatively, you might want to handle events outside the
request-response cycle. This can be achieved by only registering the
model event source e.g. in a management command, and then sending all
model instances through all event sources, and directly processing those
events, for example like this:

.. code-block:: python

from spark import api


# Copied from the process_spark_sources management command inside
# this repository
for model, sources in api.MODEL_SOURCES.items():
for instance in model.objects.all():
for source in sources:

- `Documentation <>`_
- `Github <>`_

Project details

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Filename, size & hash SHA256 hash help File type Python version Upload date
django_spark-0.3.0-py2.py3-none-any.whl (17.0 kB) Copy SHA256 hash SHA256 Wheel py2.py3
django-spark-0.3.0.tar.gz (12.1 kB) Copy SHA256 hash SHA256 Source None

Supported by

Elastic Elastic Search Pingdom Pingdom Monitoring Google Google BigQuery Sentry Sentry Error logging AWS AWS Cloud computing DataDog DataDog Monitoring Fastly Fastly CDN SignalFx SignalFx Supporter DigiCert DigiCert EV certificate StatusPage StatusPage Status page