Manage cron jobs with python-crontab

Cron is the main time based scheduler for any linux based system and is available in almost every distro. And in a recent project I had the task to manage jobs in cron from python. Searching for a good cron manager I came across python-crontab. It makes it really easy to manage jobs directly from cron, here are some examples:
NOTE: This examples used version 0.9.6, there’s a new version available 1.2 on pypi along with some examples, the main difference is that the API has been changed from slice calls to be properties instead of methods.

Installing python-crontab is easy as pie. First we install our virtual enviroment:

cd /var/www
python virtualenv.py --no-site-packages prj-env
cd prj-env
bin/activate

Then we proceed to install python-crontab

pip install python-crontab
or
easy_install python-crontab

Let’s schedule a job to be executed everyday at 12pm

from crontab import CronTab
"""
Here the object can take two parameters one for setting
the user cron jobs, it defaults to the current user
executing the script if ommited. The fake_tab parameter
sets a testing variable. So you can print what could be
written to the file onscreen instead or writting directly
into the crontab file.
"""
tab = CronTab(user='www',fake_tab='True')
cmd = '/var/www/pjr-env/bin/python /var/www/PRJ/job.py'
# You can even set a comment for this command
cron_job = tab.new(cmd, comment='This is the main command')
cron_job.minute().on(0)
cron_job.hour().on(12)
#writes content to crontab
tab.write()
print tab.render()

It will print out

0 12 * * * /var/www/pjr-env/bin/python /var/www/PRJ/job.py

If we want to schedule a job to be executed every five minutes we could do something like this

from crontab import CronTab
tab = CronTab(user='www',fake_tab='True')
cmd = '/var/www/pjr-env/bin/python /var/www/PRJ/job.py'
cron_job = tab.new(cmd)
cron_job.minute().every(5)
#writes content to crontab
tab.write()
print tab.render()

It will print out

*/5 * * * * /var/www/pjr-env/bin/python /var/www/PRJ/job.py

If we want to schedule a job for a specific range of hours for example only working hours, we could do the following

from crontab import CronTab
tab = CronTab(user='www',fake_tab='True')
cmd = '/var/www/pjr-env/bin/python /var/www/PRJ/job.py'
cron_job = tab.new(cmd)
cron_job.minute().on(0)
cron_job.hour().during(09,18)
#writes content to crontab
tab.write()
print tab.render()

It will print out

0 09-18 * * * /var/www/pjr-env/bin/python /var/www/PRJ/job.py

Now to schedule a job to run twice a day at 11 and 16 hrs, we could do the following

from crontab import CronTab
tab = CronTab(user='www',fake_tab='True')
cmd = '/var/www/pjr-env/bin/python /var/www/PRJ/job.py'
cron_job = tab.new(cmd)
cron_job.minute().on(0)
cron_job.hour().on('11,16')
#writes content to crontab
tab.write()
print tab.render()

it will print out

0 11,16 * * * /var/www/pjr-env/bin/python /var/www/PRJ/job.py

Let’s delete the previous command

from crontab import CronTab
cmd = '/var/www/pjr-env/bin/python /var/www/PRJ/job.py'
tab = CronTab(user='www',fake_tab='True')
cron_job = tab.find_command(cmd)
if len(cron_job) > 0:
    tab.remove_all(cmd)
#writes content to crontab
tab.write()

So there you have it, examples that make python-crontab a great python manager for cron jobs. Now I know there are pure Python implementations like this, an event scheduler named sched and libraries like Kronos. But I decided to keep things simple.

 

webjunkie

 

11 thoughts on “Manage cron jobs with python-crontab

  1. I encountered some errors while using your example code.
    cron_job.minute().on(0) gave an error.
    I resolved by using this instead:
    cron_job.minute.on(0)
    Besides that, thanks for sharing. Your post helped me out.

    1. Hi Michael,
      Ah it must be because there’s a new version, I was using version 0.9.6. From version 1.0 and up there was a change in the API of slice calls to be properties instead of methods.
      Thanks for the heads up, I’ve put a note in the post.
      Cheers!.

      1. thank you, the problem was resolved
        but can I delete the cronjob based comment?
        I use this script but can not remove it
        from crontab import CronTab
        cron = crontab ()
        comment = ‘myJob’
        cron_job = cron.find_comment (‘comment)
        for list in cron_job:
             cron.remove_all (cron_job)
        cron.write ()
        if there is something wrong with the script…

        1. You should do:
          cron.remove_all(comment=’comment’)
          OR
          for item in cron.find_comment(‘comment’):
          cron.remove(item)
          If you ask it to remove_all for an item, it will remove nothing.

  2. Hi I’m using your module and I’m trying to cancel right job, not only with cmd filter but entire information about it.
    I tried your samples and other version samples but I found an error with job.day.on() method doesn’t exist but —> job.dom.on() works (dom=day of month).
    Any find example for deleting right job (with all information about it)?
    cron_job = tab.find_command(cmd) give me too much similar command I’m scheduling on all days, but I want to change only one .
    for example:
    0 8 0 1 * /myjobs/start.sh
    0 20 0 1 * /myjobs/stop.sh
    0 9 0 2 * /myjobs/start.sh
    0 18 0 2 * /myjobs/stop.sh
    0 4 0 3 * /myjobs/start.sh
    0 13 0 3 * /myjobs/stop.sh
    how can I find and modify or cancel dom 2 couple of jobs?

  3. Hi,
    I get an IOError on “system_cron = CronTab()” –> no crontab for root…
    But when I run the “crontab -l” command I get an empty crontab for root.
    I don’t know what I am doing wrong

  4. Do you happen to know of an efficient way to take a string like ‘0 19 * * 1-5’ and put that into a cronjob?
    I’m taking the value of a variable which is in this form ‘0 19 * * 1-5’ and I need to make a cronjob.

  5. Is there a way to have the command that is actually split between two days, for example, running a command every 2 mins from 7 pm to 3 am till next morning

Leave a Reply to Sam Cancel reply

Your email address will not be published. Required fields are marked *