Skip to content


Subversion checkout URL

You can clone with
Download ZIP
Tree: aa82034ade
Fetching contributors…

Cannot retrieve contributors at this time

142 lines (102 sloc) 4.81 KB
Using ``brabeion``
Getting Started
.. class:: brabeion.base.Badge
``brabeion`` works by allowing you to define your badges as subclasses of a
common ``Badge`` class and registering them with ``brabeion``. For example if
your site gave users points, and you wanted to award three ranks of badges
based on how many points a user had your badge might look like this:
.. sourcecode:: python
from brabeion import badges
from brabeion.base import Badge, BadgeAwarded
class PointsBadge(Badge):
slug = "points"
levels = [
events = [
multiple = False
def award(self, **state):
user = state["user"]
points = user.get_profile().points
if points > 10000:
return BadgeAwarded(level=3)
elif points > 7500:
return BadgeAwarded(level=2)
elif points > 5000:
return BadgeAwarded(level=1)
There are a few relevant attributes and methods here.
.. attribute:: slug
The unique identifier for this ``Badge``, it should never change.
.. attribute:: levels
A list of the levels available for this badge (if this badge doesn't have
levels it should just be a list with one item). It can either be a list of
strings, which are the names of the levels, or a list of
:class:`brabeion.base.BadgeDetail` which have both names and description.
.. attribute:: events
A list of events that can possibly trigger this badge to be awarded. How
events are triggered is described in further detail below.
.. attribute:: multiple
A boolean specifying whether or not this badge can be awarded to the same
user multiple times, currently if this badge has multiple levels this must
be ``False``.
.. method:: award(self, **state)
This method returns whether or not a user should be awarded this badge.
``state`` is guarnteed to have a ``"user"`` key, as well as any other
custom data you provide. It should return either a ``BadgeAwarded``
instance, or ``None``. If this ``Badge`` doesn't have multiple levels
``BadgeAwarded`` doesn't need to be provided an explicit level.
.. note::
``BadgeAwarded.level`` is 1-indexed.
Now that you have your ``PointsBadge`` class you need to be able to tell
``brabeion`` when to try to give it to a user. To do this, any time a user
*might* have received a badge just call ``badges.possibly_award_badge`` with
the name of the event, and whatever state these events might need and
``brabeion`` will handle the details of seeing what badges need to be awarded
to the user:
.. sourcecode:: python
from brabeion import badges
def my_view(request):
if request.method == "POST":
# do some things
badges.possibly_award_badge("points_awarded", user=request.user)
# more view
By default badges will be awarded at the current time, if you need to overide
the award time of the badge you can pass a ``force_timestamp`` keyword argument
to ``possibly_award_badge()``.
Asynchronous Badges
.. note::
To use asynchronous badges you must have
`celery <>`_ installed and configured.
If your ``Badge.award()`` method takes a long time to compute it may be
prohibitively expensive to call during the request/response cycle. To solve
this problem ``brabeion`` provides an ``async`` option to ``Badges``. If this
is ``True`` ``brabeion`` will defer calling your ``award()`` method, using
``celery``, and it will be called at a later time, by another process (read the
`celery docs <>`_ for more information on how
``celery`` works).
Because ``award()`` won't be called until later you can define a ``freeze()``
method which allows you to provide and additional state that you'll need to
compute ``award()`` correctly. This may be necessary because your ``Badge``
requires some mutable state.
.. sourcecode:: python
class AddictBadge(Badge):
# stuff
async = True
def freeze(self, **state):
state["current_day"] =
return state
In this example badge the user will be awarded the ``AddictBadge`` when they've
visited the site every day for a month, this is expensive to calculate so it
will be done outside the request/response cycle. However, what happens if they
visit the site right before midnight, and then the ``award()`` method isn't
actually called until the next day? Using the freeze method you can provide
additional state to the ``award()`` method.
Jump to Line
Something went wrong with that request. Please try again.