Skip to content
Advertisement

Output Dates in Celery Crontab Schedule to Django Template

I’m using Celery for my Django project and I’ve scheduled some crontab tasks to send emails out to users at certain times. I need to output a schedule in an HTML/Django template that shows the dates that users can expect the emails to go out on. My crontab schedule looks like this for Celery:

import os
from celery import Celery
from celery.schedules import crontab

app = Celery("myapp")
app.config_from_object("django.conf:settings", namespace="CELERY")
app.autodiscover_tasks()


@app.task(bind=True)
def debug_task(self):
    print("Request: {0!r}".format(self.request))

first_monday_april_to_july = crontab(
    minute=15, hour=6, day_of_week="monday", day_of_month="1-7", month_of_year="4,5,6,7"
)
august_every_monday_first_two_weeks = crontab(
    minute=15, hour=6, day_of_week="monday", day_of_month="1-14", month_of_year="8"
)
august_weekdays_second_two_weeks = crontab(
    minute=15, hour=6, day_of_week="mon-fri", day_of_month="15-31", month_of_year="8"
)

app.conf.beat_schedule = {
    "report1": {
        "task": "email_report",
        "schedule": first_monday_april_to_july,
    },
    "report2": {
        "task": "email_report",
        "schedule": august_every_monday_first_two_weeks,
    },
    "report3": {
        "task": "email_report",
        "schedule": august_weekdays_second_two_weeks,
}

I was hoping to be able to grab all of the dates that the emails will be sent on from these tasks and save them into a list in the view and then send it to the template to be displayed in a table. Is something like this possible? I’m not having any luck finding a way to do this so far.

Advertisement

Answer

I ended up creating a function to grab all of the dates from the tasks and then append them all to a schedule list and then passed that through the view to the template to be output in a table. It looks like this:

from datetime import date, datetime, timedelta
from .celery import (
    first_monday_april_to_july,
    august_every_monday_first_two_weeks,
    august_weekdays_second_two_weeks,
)


def get_schedule_due_dates(schedule, last_date=datetime.now().date().replace(month=12, day=31)):
    start_date = datetime.now()
    end_date = datetime.combine(last_date, datetime.max.time())
    schedules = []
    while start_date <= end_date:
        next_due_schedule = schedule.remaining_estimate(start_date)
        due_date = datetime.now() + next_due_schedule
        if due_date <= end_date:
            schedules.append(due_date)
        else:
            break
        start_date = due_date + timedelta(days=1)
    return schedules


def report_schedule(request):
    schedules = []
    schedules.extend(get_schedule_due_dates(first_monday_april_to_july))
    schedules.extend(get_schedule_due_dates(august_every_monday_first_two_weeks))
    schedules.extend(get_schedule_due_dates(august_weekdays_second_two_weeks))
    return render(
        request,
        "reports/report_schedule.html",
        {"schedules": sorted(schedules)},
    )
User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement