Simple, but rich, declarative notification framework for Django
Project description
Ahem
====
Ahem is a notifications framework for Django projects, it uses
declarative style just like Django models.
Instalation
===========
::
pip install Ahem
Add it to the list of installed apps in your settings file:
.. code:: python
# settings.py
INSTALLED_APPS = (
'ahem',
)
If you are using ``Celery``, configure the celery beat schedule variable
so periodic tasks can run:
.. code:: python
# settings.py
from ahem.loader import get_celery_beat_schedule
CELERYBEAT_SCHEDULE = get_celery_beat_schedule()
# you may add more periodic tasks after this:
CELERYBEAT_SCHEDULE.update({
'other-task': {
'task': 'mytasks.the_taks',
'schedule': crontab(...),
}
})
Documentation
=============
| Ahem can be runned both with or without
`celery <http://celery.readthedocs.org/>`__. If the celery lib can be
imported, it will try sending notifications asynchronously, else it will
send then in the same thread it was called.
| Periodic notifications will not work without celery.
| **Attention**
| Sending notifications without celery may slow down your system, please
be careful.
Notifications
-------------
To define notifications, create a ``notifications.py`` file in any of
the installed apps of your project and create a class that extends ahem
``Notification`` class.
.. code:: python
# my_django_app/notifications.py
from datetime import timedelta
from ahem.notification import Notification
from ahem.scopes import QuerySetScope
from ahem.triggers import DelayedTrigger
class MyProjectNotification(Notification):
name = 'my_project'
scope = QuerySetScope()
trigger = DelayedTrigger(timedelta(days=1))
backends = ['email']
templates = {
'default': 'path/to/template.html'}
- ``name`` will be used as the id of your notification, it should be
unique in your project.
- ``scope`` defines which users will receive the notification.
- ``trigger`` defines how and when the notification will be triggered.
- ``backends`` is a list of available backend names for the
notification.
- ``templates`` dictionary with templates to be used for each backend.
Context
-------
get\_context\_data(self, user, backend\_name, \*\*kwargs):
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You can override ``get_context_data`` to add more variables to the
context. ``User`` is added to context by default, remember to call
``super`` if overriding.
.. code:: python
class TheNotification(Notification):
...
def get_context_data(self, user, backend_name, **kwargs):
kwargs = super(TheNotification, self).get_context_data(
user, backend_name, **kwargs)
kwargs['extra_context'] = 'This will be shown in the notification'
return kwargs
Backends
--------
Currently, ``EmailBackend`` is the only backend available. Developers
are encouraged to build new ones and merge then to this repository via
Pull Request.
Registering users in a backend
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Before sending a notification to a user using a specific backend, you
need to register it.
.. code:: python
from ahem.utils import register_user
register_user('backend_name', user,
setting1='username', setting2='secure_key')
EmailBackend
~~~~~~~~~~~~
- name: ``email``
- settings: no settings required. The ``User`` email will be used.
Context data
''''''''''''
- ``subject`` will be used as the email subject.
- ``from_email`` the email the message will be sent from, default is
DEFAULT\_FROM\_EMAIL.
- ``use_html`` if true, the email will be sent with html content type.
Scheduling a notification
-------------------------
Use the ``schedule`` method to trigger a notification. Use the
``context`` kwarg to pass a context dictionary to the notification.
.. code:: python
# this will trigger the notification according to it's `trigger`
# for the MyProjectNotification, it will wait 1 day before sending
# the notification.
MyProjectNotification.schedule(context={'some_param': 'value'})
Overriding backends
~~~~~~~~~~~~~~~~~~~
You can also limit the backends that will be used by passing a list to
the ``backends`` kwarg.
**Since the EmailBackend is currently the only one available, this
feature is currently useless**
.. code:: python
MyProjectNotification.schedule(backends=['email'])
Overriding trigger
~~~~~~~~~~~~~~~~~~
You can also explicitly tell when the notification should be sent by
passing ``delay_timedelta`` or ``eta``.
.. code:: python
# Notification will be sent at 23:45
from celery.schedules import crontab
MyProjectNotification.schedule(eta=crontab(crontab(hour=23, minute=45)))
# Notification will be send 20 minutes after it was scheduled
from datetime import timedelta
MyProjectNotification.schedule(delay_timedelta=timedelta(minutes=20))
Scopes
------
Scopes are a declarative way to select which users will receive the
notification when it's executed. Ahem comes with 2 scopes by default,
but if you are feeling adventurous you can build your onw one.
QuerySetScope
~~~~~~~~~~~~~
``QuerySetScope`` will return all users if no argument is passed but you
can pass a queryset to filter only the ones you desire.
.. code:: python
from ahem.scopes import QuerySetScope
class TheNotification(Notification):
...
scope = QuerySetScope(User.objects.filter(is_staff=True))
...
This will scope the notification only to staff users.
ContextFilterScope
~~~~~~~~~~~~~~~~~~
``ContextFilterScope`` filters the ``User`` model according to a param
specified in the context passed to the notification when it's scheduled.
.. code:: python
from ahem.scopes import ContextFilterScope
class TheNotification(Notification):
...
scope = ContextFilterScope(
context_key='user_is_admin', lookup_field='is_admin')
...
# This will send the notification only to non admin users
TheNotification.schedule(context={'user_is_admin': False})
filter\_scope(self, queryset, context)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Extra filters can be performed in the ``Notification`` ``scope`` by
adding a ``filter_scope`` method to your notification. This method
should return a list of ``User``\ s
.. code:: python
# This will restrict the notification to users with `first_name` "Camila"
class TheNotification(Notification):
...
scope = QuerySetScope(User.objects.filter(is_staff=True))
def filter_scope(self, queryset, context):
return queryset.filter(first_name='Camila').all()
Triggers
--------
Triggers define when notifications will be send. Currently the two types
of triggers available are: ``DelayedTrigger`` and ``CalendarTrigger``,
but you can also write custom ones by extending ``NotificationTrigger``.
DelayedTrigger
~~~~~~~~~~~~~~
``DelayedTrigger``\ s should receive a timedelta as their first param.
This will specify how long should be waited before sending the
notification. If a timedelta is not specified, the notification will be
imediately sent. You can optitionaly pass ``at_hour`` and/or
``at_minute`` kwargs. By doing this, after timedelta is added to the
current time, the hour and minute will be overwriten to the ones you
specified.
.. code:: python
from datetime import timedelta
from ahem.triggers import DelayedTrigger
# Will send 2 days after scheduled at 18:00.
class TheNotification(Notification):
...
trigger = DelayedTrigger(timedelta(days=2), at_hour=18, at_minute=0)
...
CalendarTrigger
~~~~~~~~~~~~~~~
``CalendarTrigger`` are periodic notifications, use ``Celery``
``crontab`` to define it's periodicity. See ``Celery`` documentation for
more info:
http://celery.readthedocs.org/en/latest/userguide/periodic-tasks.html#crontab-schedules
.. code:: python
from celery.schedules import crontab
from ahem.triggers import CalendarTrigger
# Will send notifications everyday at midnight
class TheNotification(Notification):
...
trigger = CalendarTrigger(crontab(hour=0, minute=0))
...
Templates
---------
``templates`` specify which template should be used to render
notification content. There should be at least a ``default`` template,
but you can specify a different one for each backend. When rendering the
template, all context variables will be available.
.. code:: python
class TheNotification(Notification):
...
templates = {
'default': 'path/to/your/template.html',
'email': 'path/to/email/template.html'}
Tests
-----
Use ``tox`` to run tests.
====
Ahem is a notifications framework for Django projects, it uses
declarative style just like Django models.
Instalation
===========
::
pip install Ahem
Add it to the list of installed apps in your settings file:
.. code:: python
# settings.py
INSTALLED_APPS = (
'ahem',
)
If you are using ``Celery``, configure the celery beat schedule variable
so periodic tasks can run:
.. code:: python
# settings.py
from ahem.loader import get_celery_beat_schedule
CELERYBEAT_SCHEDULE = get_celery_beat_schedule()
# you may add more periodic tasks after this:
CELERYBEAT_SCHEDULE.update({
'other-task': {
'task': 'mytasks.the_taks',
'schedule': crontab(...),
}
})
Documentation
=============
| Ahem can be runned both with or without
`celery <http://celery.readthedocs.org/>`__. If the celery lib can be
imported, it will try sending notifications asynchronously, else it will
send then in the same thread it was called.
| Periodic notifications will not work without celery.
| **Attention**
| Sending notifications without celery may slow down your system, please
be careful.
Notifications
-------------
To define notifications, create a ``notifications.py`` file in any of
the installed apps of your project and create a class that extends ahem
``Notification`` class.
.. code:: python
# my_django_app/notifications.py
from datetime import timedelta
from ahem.notification import Notification
from ahem.scopes import QuerySetScope
from ahem.triggers import DelayedTrigger
class MyProjectNotification(Notification):
name = 'my_project'
scope = QuerySetScope()
trigger = DelayedTrigger(timedelta(days=1))
backends = ['email']
templates = {
'default': 'path/to/template.html'}
- ``name`` will be used as the id of your notification, it should be
unique in your project.
- ``scope`` defines which users will receive the notification.
- ``trigger`` defines how and when the notification will be triggered.
- ``backends`` is a list of available backend names for the
notification.
- ``templates`` dictionary with templates to be used for each backend.
Context
-------
get\_context\_data(self, user, backend\_name, \*\*kwargs):
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You can override ``get_context_data`` to add more variables to the
context. ``User`` is added to context by default, remember to call
``super`` if overriding.
.. code:: python
class TheNotification(Notification):
...
def get_context_data(self, user, backend_name, **kwargs):
kwargs = super(TheNotification, self).get_context_data(
user, backend_name, **kwargs)
kwargs['extra_context'] = 'This will be shown in the notification'
return kwargs
Backends
--------
Currently, ``EmailBackend`` is the only backend available. Developers
are encouraged to build new ones and merge then to this repository via
Pull Request.
Registering users in a backend
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Before sending a notification to a user using a specific backend, you
need to register it.
.. code:: python
from ahem.utils import register_user
register_user('backend_name', user,
setting1='username', setting2='secure_key')
EmailBackend
~~~~~~~~~~~~
- name: ``email``
- settings: no settings required. The ``User`` email will be used.
Context data
''''''''''''
- ``subject`` will be used as the email subject.
- ``from_email`` the email the message will be sent from, default is
DEFAULT\_FROM\_EMAIL.
- ``use_html`` if true, the email will be sent with html content type.
Scheduling a notification
-------------------------
Use the ``schedule`` method to trigger a notification. Use the
``context`` kwarg to pass a context dictionary to the notification.
.. code:: python
# this will trigger the notification according to it's `trigger`
# for the MyProjectNotification, it will wait 1 day before sending
# the notification.
MyProjectNotification.schedule(context={'some_param': 'value'})
Overriding backends
~~~~~~~~~~~~~~~~~~~
You can also limit the backends that will be used by passing a list to
the ``backends`` kwarg.
**Since the EmailBackend is currently the only one available, this
feature is currently useless**
.. code:: python
MyProjectNotification.schedule(backends=['email'])
Overriding trigger
~~~~~~~~~~~~~~~~~~
You can also explicitly tell when the notification should be sent by
passing ``delay_timedelta`` or ``eta``.
.. code:: python
# Notification will be sent at 23:45
from celery.schedules import crontab
MyProjectNotification.schedule(eta=crontab(crontab(hour=23, minute=45)))
# Notification will be send 20 minutes after it was scheduled
from datetime import timedelta
MyProjectNotification.schedule(delay_timedelta=timedelta(minutes=20))
Scopes
------
Scopes are a declarative way to select which users will receive the
notification when it's executed. Ahem comes with 2 scopes by default,
but if you are feeling adventurous you can build your onw one.
QuerySetScope
~~~~~~~~~~~~~
``QuerySetScope`` will return all users if no argument is passed but you
can pass a queryset to filter only the ones you desire.
.. code:: python
from ahem.scopes import QuerySetScope
class TheNotification(Notification):
...
scope = QuerySetScope(User.objects.filter(is_staff=True))
...
This will scope the notification only to staff users.
ContextFilterScope
~~~~~~~~~~~~~~~~~~
``ContextFilterScope`` filters the ``User`` model according to a param
specified in the context passed to the notification when it's scheduled.
.. code:: python
from ahem.scopes import ContextFilterScope
class TheNotification(Notification):
...
scope = ContextFilterScope(
context_key='user_is_admin', lookup_field='is_admin')
...
# This will send the notification only to non admin users
TheNotification.schedule(context={'user_is_admin': False})
filter\_scope(self, queryset, context)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Extra filters can be performed in the ``Notification`` ``scope`` by
adding a ``filter_scope`` method to your notification. This method
should return a list of ``User``\ s
.. code:: python
# This will restrict the notification to users with `first_name` "Camila"
class TheNotification(Notification):
...
scope = QuerySetScope(User.objects.filter(is_staff=True))
def filter_scope(self, queryset, context):
return queryset.filter(first_name='Camila').all()
Triggers
--------
Triggers define when notifications will be send. Currently the two types
of triggers available are: ``DelayedTrigger`` and ``CalendarTrigger``,
but you can also write custom ones by extending ``NotificationTrigger``.
DelayedTrigger
~~~~~~~~~~~~~~
``DelayedTrigger``\ s should receive a timedelta as their first param.
This will specify how long should be waited before sending the
notification. If a timedelta is not specified, the notification will be
imediately sent. You can optitionaly pass ``at_hour`` and/or
``at_minute`` kwargs. By doing this, after timedelta is added to the
current time, the hour and minute will be overwriten to the ones you
specified.
.. code:: python
from datetime import timedelta
from ahem.triggers import DelayedTrigger
# Will send 2 days after scheduled at 18:00.
class TheNotification(Notification):
...
trigger = DelayedTrigger(timedelta(days=2), at_hour=18, at_minute=0)
...
CalendarTrigger
~~~~~~~~~~~~~~~
``CalendarTrigger`` are periodic notifications, use ``Celery``
``crontab`` to define it's periodicity. See ``Celery`` documentation for
more info:
http://celery.readthedocs.org/en/latest/userguide/periodic-tasks.html#crontab-schedules
.. code:: python
from celery.schedules import crontab
from ahem.triggers import CalendarTrigger
# Will send notifications everyday at midnight
class TheNotification(Notification):
...
trigger = CalendarTrigger(crontab(hour=0, minute=0))
...
Templates
---------
``templates`` specify which template should be used to render
notification content. There should be at least a ``default`` template,
but you can specify a different one for each backend. When rendering the
template, all context variables will be available.
.. code:: python
class TheNotification(Notification):
...
templates = {
'default': 'path/to/your/template.html',
'email': 'path/to/email/template.html'}
Tests
-----
Use ``tox`` to run tests.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Ahem-0.2.1.tar.gz
(9.1 kB
view details)
File details
Details for the file Ahem-0.2.1.tar.gz
.
File metadata
- Download URL: Ahem-0.2.1.tar.gz
- Upload date:
- Size: 9.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 8520250456747978d6519154734f6157eaa36f055c5f69b813e6f63ce73fedaf |
|
MD5 | cbd4ddf7166f648096c25b2f2a5ca2b9 |
|
BLAKE2b-256 | 77cfe85e85a68e1dba4bff28d288e70a7f3dd68cbbf02b6fb1d9eae3ac057201 |