Schedule Periodic Task in Django

We have heard of schedulers as in google scheduler, but have you ever used schedulers in your web applications to call some specific methods for a fixed time interval. Say a web application needs to send a mail to a user on every Monday at 7:30 p.m., then we use a scheduler to execute a defined method on every 19 hours and 30 minutes of Monday. So today we will discuss such a scheduler in the Django framework commonly known as celery beat.
 
Celery beat is a python task scheduling module. It performs specified tasks at regular intervals irrespective of any other process/event occurring. Celery is compatible with Django since it provides many predefined methods for executing asynchronously as well as synchronously tasks on schedule as well as periodically. Let's try building a periodic task using celery beat in a Django app. Firstly, we need to build a Django project, demo_project, and then within it a Django app, demo_app. Here is the terminal syntax,
  1. $ django-admin startproject demo_project  
  2. $ cd demo_project  
  3. $ python manage.py startapp demo_app    
Now, we need to install celery beat in our virtual environment by using a simple command,
  1. $ pip install django-celery-beat  
After installation, we will need to configure our demo_project's settings by adding 2 installed apps 'demo_app' and 'django_celery_beat' in settings.py like this,
  1. INSTALLED_APPS = [  
  2.     # other apps ...
  3.     'demo_app',  
  4.     'django_celery_beat',  
  5. ]   
Celery beat requires to store some data in the database in order to schedule task periodically. Hence we will create the tables for the same by the terminal syntax,
  1. $ python manage.py migrate  
So, we are ready to create our periodic task. We will create a new file in demo_app named 'tasks.py' and then within it define a task which prints a message for every Thursday at 7:30 a.m to all its users. Here is how the task is defined,
  1. from __future__ import absolute_import, unicode_literals    
  2. from celery import shared_task    
  3.   
  4. @shared_task    
  5. def test(message):    
  6.     print(f"Message: {message}")    
Then, we need to configure our demo_project to perform the test task on every Thursday at 7:30 a.m. This can be done by creating 'celery.py' in demo_project and set a schedule by specifying the beat_schedule dictionary with the keys 'task', 'schedule' and 'args' as shown below,
  1. from __future__ import absolute_import, unicode_literals  
  2.   
  3. import os  
  4. from celery import Celery  
  5. from celery.schedules import crontab  
  6.   
  7. os.environ.setdefault('DJANGO_SETTINGS_MODULE''demo_project.settings')  
  8. # celery settings for the demo_project  
  9. app = Celery('demo_project')  
  10. app.config_from_object('django.conf:settings', namespace='CELERY')  
  11. # here is the beat schedule dictionary defined  
  12. app.conf.beat_schedule = {  
  13.     'print-every-thrusday': {  
  14.         'task''demo_app.tasks.test',  
  15.         'schedule': crontab(hour=7, minute=30, day_of_week=4),  
  16.         'args': ('Its Thrusday!',)  
  17.     },  
  18. }  
  19. app.conf.timezone = 'UTC'  
  20. app.autodiscover_tasks()  
Crontab schedules help to decide when the task is executed, for example, a particular time of day or day of the week, or even month of the year. Likewise, there are solar schedules that allow you to schedule your task according to sunrise, sunset, dawn, or dusk by providing the latitude and longitude of the place. So that's it, we have scheduled a task in a web application independent of client-server interactions on a periodic interval using celery beat. To learn more about celery, click here to get to the source.