Celery is a distributed task queue that allows you to run tasks from your Python app or script. It allows you to run your tasks asynchronously.  It means you don’t have to wait for this function. In this tutorial, we’re going to learn about How to send emails Asynchronously? You can execute your script by simply sending it to Celery and it will run your script on demand. It usually needs a broker for transferring the tasks in this article we will use RabbitMQ.

The process of celery goes like this:

Client -> Django -> Rabbitmq -> Celery

Django is an open-source and free high-level web application framework for python. Django is used for its clean design, rapid development, easy maintenance, and secure website.

Prerequisites

  1. Python 3
  2. An IDE of your preference
  3. Django 3
  4. Virtual environment
  5. RabbitMQ
  6. Celery

Step -1: Installing required packages

You can simply install Django by typing the below command in your command prompt or the terminal:

pip3 install django

Virtualenv is a tool for creating a separate space from the system. Virtualenv has its own environment you can run python code separate from the system and it doesn’t affect the system. It’s very helpful for developing a new and multiple software without interfering in each other processes. For installing virtualenv you can run the below command in your terminal:

pip3 install python3-venv

Now let’s create a folder for our project:

mkdir sende
cd sende

Now, let’s initialize the virtual environment for our project and activate it:

python3 -m venv djangoenv  
source djangoenv/bin/activate  

After that, you can run all code for sending an email using celery in this virtual environment. It’s time to install the RabbitMQ. It is open-source message broker software that gives you access to a common platform for sending and receiving messages.

Use the below command to install RabbitMQ:

For MacOS:

brew install rabbitmq

For Windows, you can download it from here, and for Linux download it from here.

Now, let’s install Celery:

pip3 install celery

Step -2: Configuring Celery

Start a new project using the below command:

django-admin startproject celery_project 

First, enable then start rabbit MQ server by simply using this command in your terminal:

sudo systemctl enable rabbitmq-server
sudo systemctl start rabbitmq-server

You can check the server is working or not using the below command:

sudo systemctl status rabbitmq-server

To use Django with celery first we need to define an instance of celery. For this go to your main folder of the project and create a new file named ‘celery.py’ and configure it. Open celery.py in your IDE and run this command:

from_future_import absolute_import, unicode_literals
import os
from celery import celery

Next, we have to set the Django settings module environment variables for the celery command-line program:

os.environ.setdefault('DJANGO_SETTING_MODULE' , 'celery_project.settings')

After that, we create an app instance:

app = celery ('celery_project')

Then we add the Django settings module as a configuration source for celery:

App.config_from_object('django.conf:settings' , namespace='CELERY')

Next, we are going to use the app auto-discovery task that we have in other applications. We are going to define tasks for celery to run. tasks are placed inside of tasks.py and auto-discover is going to find the tasks file and import the file for celery to run.

app autodiscover_tasks()

Adding the code in the setting.py

EMAIL_BACKEND ='django.core.mail.backends.smtp.EmailBackend
#add your host of the email here in this case its Gmail so we are going to use Gmail host
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_USE_TLS = True
#add the port number of the email server
EMAIL_PORT = 587
#add your gamil here
EMAIL_HOST_USER = '[email protected]'
#add your password here
EMAIL_HOST_PASSWORD = 'password'

Updating the __init__.py

We need to update our __init__.py file for that you can simply paste the code given below in your __init__.py file.

from celery import app as celery
_app__all__ = ('celery_app',)

Step -3: Creating view

We are going to create a view.py in our project app that we can use and that’s going to trigger everything for celery you can paste this code in that view.py.

from django.shortcuts import render
def index(request):   
    return HttPresopnse('Done!')

Step -4: Configuring Gmail settings

Configure the Gmail id for Django:

  1. Go to your email id then manage your account 
  2. Then go to security scroll down and turn the Less secure app access on
  3. Next turn on the 2-step verification
  4. After that, you can see the new option app password
  5. Generate the app password
  6. And copy-paste it somewhere

Now, update settings.py with your credentials.

Step -5: Creating mail.py

Create the mail.py file in the celery folder and copy-paste this code into the file. We already define the value of the email, host, user in the setting.py so we can import the value in the file.

from django.core.mail import send_mail
from project.settings import EMAIL_HOST_USER
def send_mail_to(subject, message, receivers):   
    send_mail(subject,message,EMAIL_HOST_USER,[receivers],   fail_silently= False)

Now that we have done with downloading and configuring the celery let’s create the task in celery that can send emails.

Step -6: Creating task for Celery

First, we need to create an app for that type the below command in your terminal:

python3 manage.py startapp.task

After creating the task.py paste the below code into the file:

#import the task from celery
from celery.decorators import task
from celery.utils.log import get_task_logger
from time import time
from .celery.inform_using_mail import send_mail_tosleeplogger = get_task_logger(__name__)@task(name='first_task')def 
my_first_task(duration):

   #add your subject of the email   
   subject= 'sending emails using celery'
   #add your message 
   message= 'hello this is my first send email with celery using Django’
   #adding email of the receiver    
   receiver= '[email protected]'   
   is_task_completed= False   error=''   
   try:       
      sleep(duration)       
      is_task_completed= True   
   except Exception as err:       
      error= str(err)       logger.error(error)   
   if is_task_completed:       
      send_mail_to(subject,message,receivers)   
   else:       
      send_mail_to(subject,error,receivers)   
      return('first_task_done')

We need to restart the worker from the terminal to run the task. For that paste the below command in the terminal.

service supervisor restart

After running this code our task should run. This tutorial will not only help you on how to send emails asynchronously but also help you to run tasks in an async manner.

Final Words

In this article, we learn How to send emails asynchronously using celery, rabbitMQ, and virtualenv. Celery is very useful software for performing automatic tasks and scheduling tasks.

Let us know if you guys have any questions/comments regarding this process.

Happy coding!