You want to manage your cron jobs with Python and Plan? Here you can learn that by this tutorial. In this tutorial I will show you how to use Plan to do cron jobs in Python. After this you should be easily creating your own cron jobs and learn the common patterns of Plan.

If you want the full source code, check out example source.


We will explain our needs here, basically we want to do the following things:

  1. We want to log our server running status every 4 hours.
  2. We are running one Python web application and want to run a few scripts at different times.
  3. As time goes on, I have a few more commands and scripts to run.


Let’s get our basic schedule file:

$ mkdir schedule
$ cd schedule
$ plan-quickstart

Now you can see a schedule.py under your schedule directory, plan-quickstart is the command that comes with Plan for creating one example file, you can run plan-quickstart --help for more details. Then you can modify this file for your own needs, the file looks like this:

# -*- coding: utf-8 -*-

# Use this file to easily define all of your cron jobs.
# It's helpful to understand cron before proceeding.
# http://en.wikipedia.org/wiki/Cron
# Learn more: http://github.com/fengsp/plan

from plan import Plan

cron = Plan()

# register one command, script or module
# cron.command('command', every='1.day')
# cron.script('script.py', path='/web/yourproject/scripts', every='1.month')
# cron.module('calendar', every='feburary', at='day.3')

if __name__ == "__main__":

One Command

Let’s begin with one little command, quite clear:

cron.command('top', every='4.hour', output=

Run python schedule.py and run it with check mode, you will see the following cron syntax content:

# Begin Plan generated jobs for: main
0 0,4,8,12,16,20 * * * top >> /tmp/top_stdout.log 2>> /tmp/top_stderr.log
# End Plan generated jobs for: main

When you call run(), you can choose which run-type(default to be check) you want to use, for more details on run types, check Run Types out.


I have one script I want to run every day:

cron.script('script.py', every='1.day', path='/web/yourproject/scripts',
            environment={'YOURAPP_ENV': 'production'})

And now we have one more cron entry:

0 0 * * * cd /web/yourproject/scripts && YOURAPP_ENV=production python script.py

More Jobs

As time goes on, I have more cron jobs. For example, I have 10 more scripts under /web/yourproject/scripts and 10 more commands to run. Now we have to think about how to manage these tons of jobs, first we do not want to put these jobs in one place, second we do not want to repeat the same path and environment parameter on all script jobs. Luckily, you can do that easily with Plan, basically, every Plan instance is a group of cron jobs:

$ cp schedule.py schedule_commands.py
$ cp schedule.py schedule_scripts.py

Now we modify schedule_commands.py:

from plan import Plan

cron = Plan("commands")

cron.command('top', every='4.hour', output=
cron.command('yourcommand', every='sunday', at='hour.12 minute.0 minute.30')
# more commands here

if __name__ == "__main__":

Then schedule_scripts.py:

from plan import Plan

cron = Plan("scripts", path='/web/yourproject/scripts',
            environment={'YOURAPP_ENV': 'production'})

cron.script('script.py', every='1.day')
cron.script('script_2.py', every='1.month', at='hour.12 minute.0')
# more scripts here

if __name__ == "__main__":

A problem arises, how do you update your crontab content when you have two schedule files, it is simple, do not use write run-type, instead use update run-type here. write run-type will replace the whole crontab cronfile content with that Plan object’s cron content, update will just add or update the corresponding block distinguished by your Plan object name (here is "commands" and "scripts").

If you are still interested, now is your time to move on to the next part.

Table Of Contents

Related Topics

This Page

Fork me on GitHub