Think of crontabs as a quick-and-dirty solution you can throw into one-off python scripts to execute tasks on a cron-like schedule.
Crontabs is a small pure-python library that was inspired by the excellent schedule library for python.
In addition to having a slightly different API, crontabs differs from the schedule module in the following ways.
Python has no shortage of cron-like job scheduling libraries, so why create yet another. The honest answer is that I couldn't find one that met a simple list of criteria.
pip install crontabs
from crontabs import Cron, Tab
from datetime import datetime
def my_job(*args, **kwargs):
print('args={} kwargs={} running at {}'.format(args, kwargs, datetime.now()))
# Will run with a 5 second interval synced to the top of the minute
Cron().schedule(
Tab(name='run_my_job').every(seconds=5).run(my_job, 'my_arg', my_kwarg='hello')
).go()
from crontabs import Cron, Tab
from datetime import datetime
def my_job(*args, **kwargs):
print('args={} kwargs={} running at {}'.format(args, kwargs, datetime.now()))
# All logging messages are sent to sdtout
Cron().schedule(
# Turn off logging for job that runs every five seconds
Tab(name='my_fast_job', verbose=False).every(seconds=5).run(my_job, 'fast', seconds=5),
# Go ahead and let this job emit logging messages
Tab(name='my_slow_job').every(seconds=20).run(my_job, 'slow', seconds=20),
).go()
from crontabs import Cron, Tab
from datetime import datetime
def my_job(*args, **kwargs):
print('args={} kwargs={} running at {}'.format(args, kwargs, datetime.now()))
Cron().schedule(
Tab(
name='future_job'
).every(
seconds=5
).starting(
'12/27/2017 16:45' # This argument can either be parsable text or datetime object.
).run(
my_job, 'fast', seconds=5
)
# max_seconds starts from the moment go is called. Pad for future run times accordingly.
).go(max_seconds=60)
The Cron
class has a very small api
method | Description |
---|---|
.schedule() |
[Required] Specify the different jobs you want using Tab instances |
.go() |
[Required] Start the crontab manager to run all specified tasks |
.get_logger() |
A class method you can use to get an instance of the crontab logger |
The api for the Tab
class is designed to be composable and readable in plain English. It supports
the following "verbs" by invoking methods.
method | Description |
---|---|
.run() |
[Required] Specify the function to run. |
.every() |
[Required] Specify the interval between function calls. |
.starting() |
[Optional] Specify an explicit time for the function calls to begin. |
.lasting() |
[Optional] Specify how long the task will continue being iterated. |
.until() |
[Optional] Specify an explicit time past which the iteration will stop |
.during() |
[Optional] Specify time conditions under which the function will run |
.excluding() |
[Optional] Specify time conditions under which the function will be inhibited |
from crontabs import Cron, Tab
from datetime import datetime
def my_job(name):
print('Running function with name={}'.format(name))
Cron().schedule(
Tab(name='forever').every(seconds=5).run(my_job, 'my_func'),
).go()
from crontabs import Cron, Tab
from datetime import datetime
def my_job(name):
print('Running function with name={}'.format(name))
Cron().schedule(
Tab(name='forever').run(my_job, 'forever_job').every(seconds=5),
Tab(name='for_thirty').run(my_job, 'mortal_job').every(seconds=5).lasting(seconds=30),
Tab(name='real_long').run(my_job, 'long_job').every(seconds=5).until('1/1/2030'),
).go()
from crontabs import Cron, Tab
from datetime import datetime
def my_job(name):
# Grab an instance of the crontab logger and write to it.
logger = Cron.get_logger()
logger.info('Running function with name={}'.format(name))
def business_hours(timestamp):
return 9 <= timestamp.hour < 17
def weekends(timestamp):
return timestamp.weekday() > 4
# Run a job every 30 minutes during weekdays. Stop crontabs after it has been running for a year.
# This will indiscriminately kill every Tab it owns at that time.
Cron().schedule(
Tab(
name='my_job'
).run(
my_job, 'my_job'
).every(
minutes=30
).during(
business_hours
).excluding(
weekends
)
).go(max_seconds=3600 * 24 * 365)
git clone git@github.com:robdmc/crontabs.git
cd crontabs
pip install -e .[dev]
py.test -s -n 8 # Might need to change the -n amount to pass
Projects by robdmc.