Schedule tasks

The schedule: section in gramex.yaml lets you run tasks on startup or at specific times. Here are some sample uses:

Here is a sample configuration:

schedule:
    run-on-startup:
        function: logging.info(msg="Scheduled msg (on startup)")
        startup: true
    run-every-hour:
        function: schedule_utils.log_time   # Log the current time
        minutes: 0
        hours: '*'

Each named schedule section has the following keys:

Schedule timing

In addition, the schedule is specified via the minutes, hours, dates, weekdays, months and years keys.

Schedule examples

For example, this configuration runs at on the 15th and 45th minute every 4 hours on the first and last day of the month (if it’s a weekday) in 2016-17.

schedule:
  run-when-i-say:
    function: schedule_utils.log_time()
    minutes: '15, 45'           # Every 15th & 45th minute
    hours: '*/4'                # Every 4 hours
    dates: '1, L'               # On the first and last days of the month
    weekdays: 'mon-fri'         # On weekdays
    months: '*'                 # In every month
    years: '2016, 2017'         # the next 2 years

This configuration runs only on startup:

schedule:
  run-on-startup:
    function: schedule_utils.log_time()
    startup: true

This configuration runs on startup, and re-runs every time the YAML file changes:

schedule:
  run-on-startup:
    function: schedule_utils.log_time()
    startup: '*'

This configuration runs every hour on a separate thread:

schedule:
  run-every-hour:
    function: schedule_utils.log_time()
    hours: '*'
    thread: true

The scheduler uses the local time zone of the server Gramex runs on. To run on UTC (i.e. GMT), add utc: true:

schedule:
  run-on-utc-schedule:
    function: schedule_utils.log_time()
    hours: 5            # Run at 5am UTC
    utc: true

Scheduler preview

You can run schedules manually using the Admin Schedule component at /admin/schedule.

Scheduler API

You can run an existing scheduler programmatically. This code runs the schedule named run-when-i-say.

from gramex import service      # Available only if Gramex is running
gramex.service.schedule['run-when-i-say'].run()

If it has a schedule, .run() will clear past schedules and set up a new schedule.

You can create or update a scheduler dynamically. For example, this FunctionHandler changes a schedule based on the URL’s ?minutes= parameter:

from gramex.services.scheduler import Task

def update_schedule(handler):
    from gramex import service      # Available only if Gramex is running
    # If our scheduler is already set up, stop it first
    if 'custom-schedule' in service.schedule:
        service.schedule['custom-schedule'].stop()
    # Create a new scheduler with this configuration
    schedule = AttrDict(
        function=scheduler_method,            # Run this function
        minutes=handler.get_arg('minutes'),   # ... based on the URL's ?minutes=
    )
    # Set up the scheduled task. This will at the minute specified by ?minutes=
    service.schedule['custom-schedule'] = Task(
        'custom-schedule', schedule, service.threadpool)