This way you get the full power of Python's argument mechanics (mixing positional and keyword args, and can use symbolic names for names of weeks and months)

The CronTab class would be defined as simply sleeping in minute increments, and calling check() on each event. (There are probably some subtleties with daylight savings time / timezones to be wary of though). Here's a quick implementation:

You might want to add some import statements for the inexperienced. I ended up putting all the classes in a single file with from datetime import * from time import sleep and changed time.sleep to sleep. Nice, simple elegant solution. Thanks.
–
mavnnMay 8 '09 at 11:17

Just wondering, why is this being preferred over Kronos? Is sched that buggy (since kronos uses sched)? Or is this just outdated?
–
CawasApr 15 '10 at 20:29

Thanks brian, i use your solution in production and it's working quite well. However, as others have pointed out, there is a subtle bug in your run code. Also i found it overly complicated for the needs.
–
raph.amiardNov 2 '10 at 0:25

1

This is cool, but still doesn't support slash notation, for execution every hour, min, etc...
–
Chris KostonJul 6 '12 at 21:16

How come this doesn't have the highest upvotes? I've been searching for an epicly simple solution for 2 days now. This exactly fits my needs. I simply want to run a function at 00:00 GMT everyday. I've looked into sched among others, and this only solves it in the cleanest, simplest form.
–
Rexford2 days ago

sched has a number of issues, the principle of which is that it doesn't seem to support absolute scheduling (run this function every Friday at 2pm), just relative (run this function once in 10 hours 52 minutes and 30 seconds).
–
jameshDec 17 '08 at 8:56

2

@jamesh: start with sched and add features. You have the source.
–
S.LottDec 17 '08 at 21:26

@S.Lott, yes, you're right. Right now, I'm just trying to see if I can avoid inventing a square wheel.
–
jameshDec 19 '08 at 11:26

The source is with you on this one, sched is very accessible.
–
Matt JoinerSep 14 '11 at 3:17

There isn't a "pure python" way to do this because some other process would have to launch python in order to run your solution. Every platform will have one or twenty different ways to launch processes and monitor their progress. On unix platforms, cron is the old standard. On Mac OS X there is also launchd, which combines cron-like launching with watchdog functionality that can keep your process alive if that's what you want. Once python is running, then you can use the sched module to schedule tasks.

Check out luigi (https://github.com/spotify/luigi). It's written in python and has a nice web UI for monitoring tasks. It also has a dependency graph. Might be overkill for what you need but it will probably do the trick.

Yes, it's basically a race condition. If datetime.now() is < but very close to t, by the time the next line executes, the new eval of datetime.now() could be slightly > t, so the param you pass to time.sleep is a negative number of seconds. Depending on your OS and Python version, a negative number when passed to sleep can be interpreted as a large positive number due to integer underflow. It's easy to rewrite this so you only evaluate datetime.now() once. And in later versions of Python, passing in a negative number of seconds will just raise an exception.
–
Chris JohnsonApr 22 at 19:19

Be careful when posting copy and paste boilerplate/verbatim answers to multiple questions, these tend to be flagged as "spammy" by the community. If you're doing this then it usually means the questions are duplicates so flag them as such instead: stackoverflow.com/a/12360556/419
–
KevSep 10 '12 at 23:22

You can check out PiCloud's [1] Crons [2], but do note that your jobs won't be running on your own machine. It's also a service that you'll need to pay for if you use more than 20 hours of compute time a month.

The only concern for a python solution is that your job needs to be always running and possibly be automatically "resurrected" after a reboot, something for which you do need to rely on system dependent solutions.