django-scheduled-tasks: Running periodic background tasks with the 6.0 task framework

I’m excited about the addition of the 6.0 Tasks framework in Django. I’m trying it out as a light-weight Celery replacement in some hobby and professional projects.

In doing so, I’m trying to provide a package for a (to me) common use-case of background tasks:
scheduling tasks to run periodically, e.g., at certain times of day, or every hour.

It’s designed to wrap around whatever task backend you have running by registering certain tasks on a schedule, and I’ve started with support for periodic tasks (run on a time interval) and crontab-based schedules.
Usage:

from django.tasks import task
from django_scheduled_tasks import periodic_task, cron_task
from datetime import timedelta


# note the order of the decorators! Make sure periodic_task is above task
@periodic_task(interval=timedelta(hours=2))
@task
def run_hourly():
    ...


# or call periodic_task with a task directly:
@task
def some_existing_task(some_arg: str):
    ...


periodic_task(interval=timedelta(hours=3), call_args=("some_arg_value",), task=some_existing_task)


# Run at 9am every day
@cron_task(cron_schedule="0 9 * * *")
@task
def daily_report():
    ...


# Run at 9am in a specific timezone
@cron_task(cron_schedule="0 9 * * *", timezone_str="Europe/Brussels")
@task
def timezoned_scheduled_task():
    ...


If you’d like to try it out, you can check out the readme and code on the github project, or have a go installing it yourself from PyPI.

I’ve so far been building it to cover my own use cases, so it may not yet cover your needs. If this is the case, please do let me know what functionality you’d like, through a comment/issue/pr.

2 Likes

Hi there :waving_hand:,

I created a task scheduler just now. It’s based on an existing production-hardened package and should be ready to go… once we have more backends :wink:

Best,
Joe

1 Like

Cool! If you’re using apscheduler, I’d recommend looking at persisting the job results. Could allow for what I ended up doing: being able to recover from the scheduler process being down during a cron window, by keeping a model backed store of planned execution times.

That may not be something everyone cares about, but imo recoverability from reboots is a nice base robustness for any scheduling loop.

Don’t hesitate to open up a ticket! Personally, I didn’t need that. In fact, I would want to disable this on most of my projects, but I can understand that there might be scenarios where this is needed.

Meanwhile, we use Sentry to monitor execution and the code owner gets informed about issue (usually not scheduling issues, but task runtime exceptions) and the engineer decides whether a task needs to be rerun or not.