Crontab-Based Scheduling within Doctrings

How to use DocCron to create schedules

Posted 2019-05-01 11:59:25 by Ronie Martinez

For quite a while now, I have been developing DocCron. There are plenty of scheduling libraries for Python and that includes the standard library, sched. However, the only issue with these libraries is that creating schedules is not that close to what Linux guys (including me) are using, the cron or crontab. There are available libraries out there that are using the crontab syntax but you will need to write long lines of code just to create schedules.

I got inspired by the popular standard Python library, doctest. It is quite simple, you don't need to write much code aside from putting tests on docstrings. From doctest, I patterned DocCron.

Installing DocCron

To install DocCron, we simply execute any the following command.

pip install doccron  # using pip
easy_install doccron  # using easy_install

How to create schedules with DocCron?

You can write crontab style schedules in function docstrings by starting with the literal block /etc/crontab::. Crontab schedules should be written after a blank line and then indented. The example below will create a schedule that will call the function hello() every 2nd and 3rd minute. In a normal crontab syntax, there is another additional item at the end that is the command to be called. In DocCron, this has been omitted since the command that will be called is the function where the docstring is associated with.

import time


def hello():
    """
    Print "hello world" at every 2nd minute and 3rd minute:

    /etc/crontab::

        */2 * * * *
        */3 * * * *
    """
    print(time.strftime('%Y-%m-%d %H:%M:%S'), "hello world")

Simple usage

To start DocCron, the following syntax should be added at the end of the module.

if __name__ == '__main__':
    import doccron
    doccron.run_jobs()

If you take a look closely, this is similar to how we execute doctests.

if __name__ == "__main__":
    import doctest
    doctest.testmod()

Take note that functions are executed on separate threads.

 Does it support the Quartz format?

Yes! The Quartz format extends the Cron syntax by adding seconds option. This makes scheduling finer. To use the Quartz format, add quartz=True to run_jobs() function.

if __name__ == '__main__':
    import doccron
    doccron.run_jobs(quartz=True)

Timezone-awareness

Timezone can be set using the CRON_TZ variable similar to a normal crontab syntax. However, DocCron can support multiple timezones in a single docstring. If CRON_TZ does not exist, the local timezone will be used.

def hello():
    """
    Print "hello world" at every 2nd minute and 3rd minute:

    /etc/crontab::
    
        CRON_TZ=UTC
        */2 * * * *
        */3 * * * *
    """
    print(time.strftime('%Y-%m-%d %H:%M:%S%z'), "hello world")

Future support

In the next iterations, DocCron will support MAILTO variable. I am also planning to support human-readable scheduling like "tomorrow", etc.  If you want to contribute to the DocCron development, contact me or create pull requests on Github.

python doccron docstrings crontab


Share