timesched

Improved simple time scheduler based on standard sched


Keywords
sched, scheduler, timer, periodic, cron, crontab
License
GPL-3.0
Install
pip install timesched==1.8

Documentation

TIMESCHED

PyPi AUR

The timesched Python module provides a simple time event scheduler. It is implemented upon the standard Python sched module and is used in a similar way, but provides a nicer and more modern and convenient programming interface. Apart from normal oneshot and repeat timers, it can run timers at a given time of day, and for the given days of week, providing simple cron-like functionality. It requires only Python 3.6 or later, and the standard library. The latest version of this document and code is available at https://github.com/bulletmark/timesched.

class timesched.Scheduler(timefunc=time.time, delayfunc=time.sleep)

Refer to the class description for Python sched.scheduler which is used in the internal implementation of this class.

Scheduler instances have the following methods.

Create one-shot timer

oneshot(time, priority, func, *args, **kwargs)
  • time: expiry time relative to now, or absolute time. Type can be one of:
    • int at given relative seconds after now,
    • datetime.timedelta() at given relative timedelta() after now,
    • datetime.time() at given time() after now,
    • datetime.datetime() at given absolute datetime(),
    • datetime.date() at given absolute date(),
  • priority: int value, lower value is higher priority. Refer description.
  • func and args and kwargs: user function and arguments to call when timer is invoked.

Returns a timer ID which can be used to cancel the timer using cancel(timer).

Create repeating timer

repeat(period, priority, func, *args, **kwargs)
  • period: period for timer. Type can be one of:
    • int at each given seconds after now,
    • datetime.timedelta() at each given timedelta() after now,
    • datetime.time() at given time() each day after now. E.g. at 10:30 every day for simple daily "cron-like" functionality.
  • priority: int value, lower value is higher priority. Refer description.
  • func and args and kwargs: user function and arguments to call when timer is invoked.

Returns a timer ID which can be used to cancel the timer using cancel(timer).

Note that for int and timedelta() periods, the specified period is the delay between the end of the callback function and when it is called again so the actual period will slowly "creep" by the run time of the callback. Many applications are not concerned about this distinction but if necessary you can instead invoke a oneshot() absolute timer between each call.

Create one-shot timer on next given day

Call this with time = datetime.time() to invoke a oneshot() at the given time on the next day from the set of given days of the week.

oneshot_on_days(days, time, priority, func, *args, **kwargs)
  • days: A list/set/sequence/range of integers 0-6 where 0 = Monday to 6 = Sunday. e.g. [0] means only invoke timer on a Monday, [0,6] = only invoke on Monday and Sunday, etc. Using days=range(7) is same as calling ordinary oneshot().

    Alternately, you can specify days as a string "MTWTFSS" where each char is upper case if the day is to be set, and lower case if not. E.g. "MTWTFss" is the working week Mon-Fri, "mtwTfss" is Thu only, etc. A utility function to explicitly parse this string into a set of integers is available as timesched.parse_days(string_arg) if you need.

Remaining parameters and return type are same as oneshot().

Create repeating timer on given days

Call this with time = datetime.time() to invoke a repeat() at the given period on each of the given days of the week.

repeat_on_days(days, period, priority, func, *args, **kwargs)
  • days: parameter same as oneshot_on_days().

Remaining parameters and return type are same as repeat().

Return count of active timers

count()

Returns the count of timers currently active. A timer is considered active while it is pending and until it's callback function has completed, unless it is explicitly cancelled.

Cancel timer

cancel(timer)

Remove the timer with timer ID. If the timer is not currently active, this method will raise a ValueError.

Run scheduler

run(blocking=True)

Invokes the base scheduler.run(). Refer full description at Python sched module.

EXAMPLES

#!/usr/bin/python3
'Very simple examples'
import timesched
from datetime import datetime, time

# Job function to be called for each timer
def job(jobid):
    print(f'Job {jobid} called at {datetime.now()}')

# Create a scheduler
s = timesched.Scheduler()

# Execute job() once in 5 secs time
s.oneshot(5, 0, job, 1)

# Execute job() every 2 secs
s.repeat(2, 0, job, 2)

# Execute job() at 10:30am every work day (not weekends)
s.repeat_on_days('MTWTFss', time(10, 30), 0, job, 3)

# Run scheduler, will block until no timers left running
s.run()

DIFFERENCES TO STANDARD SCHED MODULE

The timesched module is internally implemented using the standard Python sched module but differs in the following ways. Note that the sched implementation, methods, and attributes are not directly exposed in the public interface.

  • Provides oneshot() and repeat() methods to conveniently accept standard datetime.datetime(), datetime.date(), datetime.time(), datetime.timedelta(), and also integer time arguments, based automatically on the type of the passed time argument.
  • The repeat() method sets itself up to be automatically invoked again at the next repeat interval, unlike sched which only provides a oneshot() equivalent method [i.e. enter() or enterabs()] so the user does not need to explicitly set up the next timer.
  • Provides a convenient way to schedule a timer at a given time each day to give simple daily "cron-like" functionality, e.g. s.repeat(datetime.time(hour=10, minute=30), f) to periodically activate a timer at 10:30 every day.
  • Further to the above repeat() which can run at a given time every day, you can use repeat_on_days() to specify a given time on a set of given days, e.g. s.repeat_on_days('MTWTFss', datetime.time(hour=10, minute=30), f) to run the timer at 10:30 each workday only (Mon to Fri). Alternately s.repeat_on_days(range(5), datetime.time(hour=10, minute=30), f) gives the same result.
  • Consistent with modern Python, allows user to plainly specify *args and **kwargs directly in timer setup call rather than in a tuple as legacy sched requires.
  • Does not provide the enter() or enterabs() methods. Use the superior oneshot(), repeat(), oneshot_on_days(), or repeat_on_days() methods instead.
  • Provides a more specific count() method instead of empty().
  • Does not provide the queue attribute.
  • Uses time.time instead of time.monotonic as the default timefunc for the internal scheduler. This is to be compatible with datetime.datetime.timestamp() which is used internally.

INSTALLATION

Arch Linux users can install timesched from the AUR.

timesched is available on PyPI so install the usual way, e.g:

pip3 install timesched

Or explicitly from github:

git clone https://github.com/bulletmark/timesched.git
cd timesched
sudo pip3 install .