Send Emails Asynchronously from Django

Last week I had the chance to get my hand dirty with Celery, I used it to send emails from Django project asynchronously using Django app call djnago-celery-email. What am I mean by sending emails asynchronously? I mean that user doesn’t wait for SMTP/mail server to send email message and give feedback to the web server, instead Django will call the send email procedure, pass it to Celery to do it away from Django application, so that user won’t wait, for example you want to send email to customer once he save customer information, you don’t want to keep user wait for application to save the customer data and send email, by sending email asynchronously user will only wait for saving confirmation and sending email celery will take care of it in the background.

Step 1: Install and Setup Celery

Now celery and its Django app djcelery are installed into your virtualenv.

Next step is to add djcelery to your Django project, go to settings.py and add ‘djcelery’ to INSTALLED_APPS.

INSTALLED_APPS=(...'djcelery',...)

Add celery.py file to your project and add the following python code in it:

from__future__importabsolute_importimportosfromceleryimportCelery# set the default Django settings module for the 'celery' program.os.environ.setdefault('DJANGO_SETTINGS_MODULE','my_app.settings')fromdjango.confimportsettingsapp=Celery(broker=settings.CELERY_BROKER_URL)app.config_from_object('django.conf:settings')app.autodiscover_tasks(settings.INSTALLED_APPS)if__name__=='__main__':app.start()

In the code above we are initiate new Celery app, and setup the broker, and last think we are telling Celery to auto discover tasks from all apps in INSTALLED_APP.

As you can see in the code we used settings.CELERY_BROKER_URL so we need to set this up in settings.py as well.

CELERY_BROKER_URL='amqp://guest:guest@localhost:5672/'

But let's me tell you what is the purpose of this, Django need to communicate with Celery, and to do so you need something that can hold and transfer messages between Django, and Celery workers, some prefer to use RabbitMQ or Redis as broker, for me I prefer RabbitMQ because it built for passing messages.

__generate_messages: used to generate the email message for us. It takes the message subject, to email addresses, and the Django template name and its context to render the template and sen the email as HTML.

__send_email(): used to send messages by using the recommended way to send emails, by open the connection with SMTP server, send all messages, then close the connection.