Jobs

The Jobs API provides a seamless way of running any function asynchronously, either ad-hoc, on a fixed interval, or on a cron schedule.

Basic Usage

The interface for this module consists of a few decorators you can use in any method, depending on the use-case you’re trying to achieve:

@jobs.background_task

Decorating a function with @background_task will allow the function to be executed asynchronously in a background worker.

Background tasks can be invoked by calling their .delay(*args, **kwargs) method:

import time
from canvas_core import jobs

@jobs.background_task
def print_message(message: str, wait: int = 0) -> None:
    time.sleep(wait)
    print(message)

# This job will be enqueued for immediate execution, and the function will
# wait 10 seconds before printing "Hello world!"
print_message.delay("Hello world!", wait=10)

@jobs.periodic_task

This decorator takes an interval argument, which will cause the function to be executed periodically on the configured time interval.

The following example will print the current timestamp every minute.

from datetime import datetime, timedelta

from canvas_core import jobs

@jobs.periodic_task(interval=timedelta(seconds=60))
def print_time() -> None:
    print(datetime.now().isoformat())

@jobs.scheduled_task

This decorator takes a schedule argument, which will execute the function on a specific time-based schedule (i.e., cron).

The following example will print the current timestamp every day at midnight.

from datetime import datetime

from canvas_core import jobs

@jobs.periodic_task(schedule=jobs.crontab(minute=0, hour=0))
def print_time() -> None:
    print(datetime.now().isoformat())

API Reference

canvas_core.jobs.background_task(fn: F) F

Make the decorated function executable asynchronously in the background.

The task can be enqueued by invoking its .delay(*args, **kwargs) method:

>>> @background_task
... def print_message(message: str) -> None:
...     print(message)
...
>>> print_message.delay("hello world")
class canvas_core.jobs.crontab(minute: str = '*', hour: str = '*', day_of_week: str = '*', day_of_month: str = '*', month_of_year: str = '*', **kwargs: Any)

Crontab schedule.

A Crontab can be used as the run_every value of a periodic task entry to add crontab(5)-like scheduling.

Like a cron(5)-job, you can specify units of time of when you’d like the task to execute. It’s a reasonably complete implementation of cron’s features, so it should provide a fair degree of scheduling needs.

You can specify a minute, an hour, a day of the week, a day of the month, and/or a month in the year in any of the following formats:

minute
  • A (list of) integers from 0-59 that represent the minutes of an hour of when execution should occur; or

  • A string representing a Crontab pattern. This may get pretty advanced, like minute='*/15' (for every quarter) or minute='1,13,30-45,50-59/2'.

hour
  • A (list of) integers from 0-23 that represent the hours of a day of when execution should occur; or

  • A string representing a Crontab pattern. This may get pretty advanced, like hour='*/3' (for every three hours) or hour='0,8-17/2' (at midnight, and every two hours during office hours).

day_of_week
  • A (list of) integers from 0-6, where Sunday = 0 and Saturday = 6, that represent the days of a week that execution should occur.

  • A string representing a Crontab pattern. This may get pretty advanced, like day_of_week='mon-fri' (for weekdays only). (Beware that day_of_week='*/2' does not literally mean ‘every two days’, but ‘every day that is divisible by two’!)

day_of_month
  • A (list of) integers from 1-31 that represents the days of the month that execution should occur.

  • A string representing a Crontab pattern. This may get pretty advanced, such as day_of_month='2-30/2' (for every even numbered day) or day_of_month='1-7,15-21' (for the first and third weeks of the month).

month_of_year
  • A (list of) integers from 1-12 that represents the months of the year during which execution can occur.

  • A string representing a Crontab pattern. This may get pretty advanced, such as month_of_year='*/3' (for the first month of every quarter) or month_of_year='2-12/2' (for every even numbered month).

nowfun

Function returning the current date and time (datetime).

app

The Celery app instance.

It’s important to realize that any day on which execution should occur must be represented by entries in all three of the day and month attributes. For example, if day_of_week is 0 and day_of_month is every seventh day, only months that begin on Sunday and are also in the month_of_year attribute will have execution events. Or, day_of_week is 1 and day_of_month is ‘1-7,15-21’ means every first and third Monday of every month present in month_of_year.

is_due(last_run_at: datetime) tuple[bool, datetime]

Return tuple of (is_due, next_time_to_run).

If :setting:`beat_cron_starting_deadline` has been specified, the scheduler will make sure that the last_run_at time is within the deadline. This prevents tasks that could have been run according to the crontab, but didn’t, from running again unexpectedly.

Note

Next time to run is in seconds.

SeeAlso:

celery.schedules.schedule.is_due() for more information.

remaining_estimate(last_run_at: ~datetime.datetime, ffwd: type = <class 'celery.utils.time.ffwd'>) timedelta

Estimate of next run time.

Returns when the periodic task should run next as a timedelta.

canvas_core.jobs.periodic_task(interval: timedelta, **options: Any) Callable[[F], F]

Makes the decorated function periodically executable asynchronously in the background.

Parameters:

interval – The interval on which to run the decorated method

canvas_core.jobs.scheduled_task(schedule: crontab, **options: Any) Callable[[F], F]

Makes the decorated function executable in the background, within the given crontab schedule.

Parameters:

schedule – A crontab object to schedule the decorated method run.