Skip to content

Instantly share code, notes, and snippets.

@phpdude
Created March 9, 2014 14:54
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save phpdude/9448981 to your computer and use it in GitHub Desktop.
Save phpdude/9448981 to your computer and use it in GitHub Desktop.
Django Simple asynchronous email backend (Celery 3.1+)
from celery import shared_task
from celery.contrib.methods import task_method
from django.core.mail.backends.smtp import EmailBackend as BaseEmailBackend
class FakeLock(object):
__enter__ = lambda x: None
__exit__ = lambda a, b, c, d: None
class EmailBackend(BaseEmailBackend):
"""
A wrapper that manages the SMTP network connection asynchronously
"""
def __init__(self, *args, **kwargs):
super(EmailBackend, self).__init__(*args, **kwargs)
# fake lock object, because base methods use this
# celery doesn't support base RLock class serialization. Fixing it.
self._lock = FakeLock()
def send_messages(self, email_messages):
self._send_messages.apply_async((self, email_messages))
return len(email_messages)
@shared_task(filter=task_method, name="send_emails")
def _send_messages(self, email_messages):
return super(EmailBackend, self).send_messages(email_messages)
# Path to class in your environment
EMAIL_BACKEND = 'project.portal.backends.asyncemail.EmailBackend'
# Don't forget add backend module to celery configuration, because it is not placed in app.tasks module and need to be defined.
CELERY_IMPORTS = ['project.portal.backends.asyncemail']
# json doesn't support serialization for python objects, only simple types.
CELERY_TASK_SERIALIZER = 'pickle'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment