Calendar scheduler
Project description
Calendar Scheduler for Recurring Events
Features
- Executes an action function on a schedule.
- Thread-safe: events can be added and canceled from different threads.
- Supports intervals from milliseconds to years.
- Uses the standard
schedscheduler. - Timezone support.
- Syntax similar to
datetime. - Events can be added at any time: before or after the scheduler starts, and from any thread.
- No additional packages required.
Installation
Install via pip:
pip install calsched
Install via uv:
uv pip install calsched
Import
from calsched import CalendarScheduler
Creating the Scheduler
scheduler = CalendarScheduler()
Running the Scheduler
Start the scheduler using the run() method:
scheduler.run()
However, it will immediately exit if no events are scheduled. At least one event must be scheduled before starting.
Example that prints the current time every second:
import datetime
from calsched import CalendarScheduler
def print_time():
print(datetime.datetime.now())
scheduler = CalendarScheduler()
scheduler.enter_every_second_event(action=print_time)
scheduler.run()
In this case, run() blocks the thread in which it is called.
The action function is executed in the same thread as the run() method.
To allow adding events after the scheduler has started, you can add a placeholder event before calling run() to keep the scheduler active:
scheduler = CalendarScheduler()
stub_event = scheduler.enter_hourly_event(action=lambda: None)
scheduler.run()
You can stop run() by canceling the placeholder event:
scheduler.cancel(stub_event)
If there are multiple events, you need to cancel all events to stop the scheduler.
Example of running in a separate thread:
import datetime
import threading
from time import sleep
from calsched import CalendarScheduler
def print_time():
print(datetime.datetime.now())
scheduler = CalendarScheduler()
stub_event = scheduler.enter_hourly_event(action=lambda: None)
thread = threading.Thread(target=scheduler.run)
thread.start()
sleep(1.0)
event = scheduler.enter_every_second_event(action=print_time)
sleep(5.0)
scheduler.cancel(stub_event)
scheduler.cancel(event)
thread.join()
Adding Events
To add events, use the enter_*_event() methods:
enter_every_millisecond_event(action=my_action, interval=N)–my_action()will be called every N milliseconds.enter_every_second_event(action=my_action, interval=N)–my_action()will be called every N seconds.enter_every_minute_event(action=my_action, interval=N)–my_action()will be called every N minutes.enter_hourly_event(action=my_action, interval=N)–my_action()will be called every N hours.enter_daily_event(action=my_action, interval=N)–my_action()will be called every N days.enter_weekly_event(action=my_action, interval=N)–my_action()will be called every N weeks.enter_monthly_event(action=my_action, interval=N)–my_action()will be called every N months.enter_yearly_event(action=my_action, interval=N)–my_action()will be called every N years.
The interval parameter must be greater than or equal to 1 and has no upper limit.
By default, the interval is 1. That is, if you do not specify the interval parameter, the event will be triggered every 1 second, 1 minute, etc., depending on the method. The exception is enter_every_millisecond_event(), where the default interval is 100 milliseconds, since a 1-millisecond interval is not feasible on real machines.
Example of a daily event that prints the current time:
import datetime
from calsched import CalendarScheduler
def print_time():
print(datetime.datetime.now())
scheduler = CalendarScheduler()
scheduler.enter_daily_event(action=print_time)
scheduler.run()
Time Parameters
An event can be scheduled for a specific moment: a particular second, minute, hour, day, and/or month.
The enter_yearly_event() method allows you to specify month, day, hour, minute, and second. Example: an event that runs 5 minutes before New Year (i.e., December 31 at 23:55:00):
scheduler.enter_yearly_event(action=my_action, month=12, day=31, hour=23, minute=55, second=0)
For monthly events, you can specify day, hour, minute, and second. Example: an event that runs on the first day of each month at 04:00:00:
scheduler.enter_monthly_event(action=my_action, day=1, hour=4, minute=0, second=0)
For monthly events, you cannot specify month, as it does not make sense. Similarly for other event types:
scheduler.enter_weekly_event(action=my_action, weekday=3, hour=4, minute=0, second=0)
scheduler.enter_daily_event(action=my_action, hour=4, minute=0, second=0)
scheduler.enter_hourly_event(action=my_action, minute=0, second=0)
scheduler.enter_every_minute_event(action=my_action, second=0)
The enter_every_second_event and enter_every_millisecond_event methods do not allow specifying execution time.
Time parameter value ranges:
- 0 <=
second<= 59, - 0 <=
minute<= 59, - 0 <=
hour<= 23, - 1 <=
day<= 31, - 0 <=
weekday<= 6 (Monday is 0, Sunday is 6), - 1 <=
month<= 12.
In enter_monthly_event() and enter_yearly_event(), if the specified day is greater than the number of days in the month, the event will be executed on the last day of the month. For example, if you specify day=31, the event will run on January 31, then on February 28 or 29 (in a leap year).
Start and End Time for Periodic Events
You can specify the start and end time for a periodic event using the start_time and end_time parameters. If not specified, the event will run indefinitely starting from the current time.
start_time– time of the first execution.end_time– time until which the event will be executed.
The start_time and end_time parameters are specified as timestamps (seconds since the Unix epoch, i.e., January 1, 1970). Typically, these values are obtained using time.time() or datetime.timestamp().
The time range is from start_time up to, but not including, end_time.
All enter_*_event() methods allow specifying start_time and end_time. Example: an event that runs every day from January 1, 2024, to January 1, 2025 (not inclusive):
start_time = datetime.datetime(2024, 1, 1, 0, 0, 0).timestamp()
end_time = datetime.datetime(2025, 1, 1, 0, 0, 0).timestamp()
scheduler.enter_daily_event(action=my_action, start_time=start_time, end_time=end_time)
Action Function Arguments
The action function can accept arguments. Use the action_args parameter for positional arguments and action_kwargs for keyword arguments.
All enter_*_event() methods allow specifying action_args and action_kwargs.
Example:
def my_action(arg1, arg2):
pass
scheduler.enter_daily_event(action=my_action, action_args=("Hello",), action_kwargs={"arg2": 123})
The scheduler will call the function as follows:
my_action("Hello", arg2=123)
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file calsched-1.1.1.tar.gz.
File metadata
- Download URL: calsched-1.1.1.tar.gz
- Upload date:
- Size: 12.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.6.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1940dd0bcf227cb51cfd403bc472c16965bc9b694143cd4837f1436d03a80459
|
|
| MD5 |
22e111cafe0d8c1bbdd435db57624dd1
|
|
| BLAKE2b-256 |
30170b8920efffe73c87e6240964597317673c109240df1c7199f059db4220bd
|
File details
Details for the file calsched-1.1.1-py3-none-any.whl.
File metadata
- Download URL: calsched-1.1.1-py3-none-any.whl
- Upload date:
- Size: 8.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.6.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
76414f703f76fa1f04875455a581247aa332ad7c6a9a5843870b78da80dd5740
|
|
| MD5 |
727dc13296e3e0618f11d9cd5ad13b07
|
|
| BLAKE2b-256 |
26ee281f4616171651f528eba903bf6dde8f7d7e544933a97ec0be672a11a853
|