The sched module provides a general-purpose event scheduler. Schedule functions to run at specific times or after delays—useful for simulations, timeouts, and timed events.
Basic Usage
Schedule a delayed function call:
import sched
import time
scheduler = sched.scheduler(time.time, time.sleep)
def say_hello(name):
print(f"Hello, {name}! Time: {time.strftime('%H:%M:%S')}")
# Schedule for 3 seconds from now
scheduler.enter(3, 1, say_hello, ('Alice',))
print(f"Starting at {time.strftime('%H:%M:%S')}")
scheduler.run() # Blocks until all events completeMultiple Events
Schedule several events:
import sched
import time
scheduler = sched.scheduler(time.time, time.sleep)
def task(name):
print(f"{time.strftime('%H:%M:%S')} - {name}")
# Schedule multiple tasks
scheduler.enter(1, 1, task, ('First',))
scheduler.enter(2, 1, task, ('Second',))
scheduler.enter(3, 1, task, ('Third',))
print(f"Started at {time.strftime('%H:%M:%S')}")
scheduler.run()Priority
Lower numbers = higher priority (runs first when times are equal):
import sched
import time
scheduler = sched.scheduler(time.time, time.sleep)
def task(name):
print(f"{name}")
# Same time, different priorities
scheduler.enter(1, 2, task, ('Low priority',))
scheduler.enter(1, 1, task, ('High priority',)) # Runs first
scheduler.run()
# Output:
# High priority
# Low priorityAbsolute Time Scheduling
Schedule for a specific time:
import sched
import time
scheduler = sched.scheduler(time.time, time.sleep)
def alarm():
print(f"ALARM! {time.strftime('%H:%M:%S')}")
# Schedule for absolute timestamp
target_time = time.time() + 5 # 5 seconds from now
scheduler.enterabs(target_time, 1, alarm)
scheduler.run()Canceling Events
import sched
import time
scheduler = sched.scheduler(time.time, time.sleep)
def task(name):
print(name)
# Schedule events
event1 = scheduler.enter(1, 1, task, ('First',))
event2 = scheduler.enter(2, 1, task, ('Second',))
event3 = scheduler.enter(3, 1, task, ('Third',))
# Cancel the second event
scheduler.cancel(event2)
scheduler.run()
# Output: First, Third (Second was canceled)Checking the Queue
import sched
import time
scheduler = sched.scheduler(time.time, time.sleep)
scheduler.enter(1, 1, lambda: print('A'))
scheduler.enter(2, 1, lambda: print('B'))
# Check if events are pending
print(f"Empty: {scheduler.empty()}") # False
print(f"Queue: {scheduler.queue}") # List of eventsNon-Blocking Check
Run events that are ready without blocking:
import sched
import time
scheduler = sched.scheduler(time.time, time.sleep)
scheduler.enter(0.1, 1, lambda: print('Quick'))
scheduler.enter(10, 1, lambda: print('Later'))
# Run with blocking=False
time.sleep(0.2) # Let first event become ready
scheduler.run(blocking=False) # Runs 'Quick', returns immediately
print("Continuing without waiting for 'Later'")Repeating Events
Create recurring tasks:
import sched
import time
scheduler = sched.scheduler(time.time, time.sleep)
def repeat(interval, func, *args):
"""Schedule a repeating task."""
func(*args)
scheduler.enter(interval, 1, repeat, (interval, func) + args)
def heartbeat():
print(f"Beat: {time.strftime('%H:%M:%S')}")
# Start repeating every 2 seconds
scheduler.enter(0, 1, repeat, (2, heartbeat))
# Run for limited time
try:
scheduler.run()
except KeyboardInterrupt:
print("Stopped")Timeout Pattern
import sched
import time
import threading
def run_with_timeout(func, timeout, *args):
"""Run function with timeout."""
result = [None]
exception = [None]
def wrapper():
try:
result[0] = func(*args)
except Exception as e:
exception[0] = e
thread = threading.Thread(target=wrapper)
thread.start()
thread.join(timeout)
if thread.is_alive():
raise TimeoutError(f"Function timed out after {timeout}s")
if exception[0]:
raise exception[0]
return result[0]Simulation Example
import sched
import time
class Simulation:
def __init__(self):
self.scheduler = sched.scheduler(time.time, time.sleep)
self.events = []
def log_event(self, message):
timestamp = time.strftime('%H:%M:%S')
self.events.append(f"{timestamp}: {message}")
print(f"{timestamp}: {message}")
def schedule(self, delay, message):
self.scheduler.enter(delay, 1, self.log_event, (message,))
def run(self):
self.scheduler.run()
# Run simulation
sim = Simulation()
sim.schedule(1, "Server started")
sim.schedule(2, "Client connected")
sim.schedule(3, "Data received")
sim.schedule(4, "Response sent")
sim.run()Countdown Timer
import sched
import time
def countdown(scheduler, seconds):
"""Display countdown timer."""
if seconds > 0:
print(f"{seconds}...")
scheduler.enter(1, 1, countdown, (scheduler, seconds - 1))
else:
print("Time's up!")
scheduler = sched.scheduler(time.time, time.sleep)
scheduler.enter(0, 1, countdown, (scheduler, 5))
scheduler.run()Rate Limiter
import sched
import time
from collections import deque
class RateLimiter:
def __init__(self, max_calls, period):
self.max_calls = max_calls
self.period = period
self.calls = deque()
self.scheduler = sched.scheduler(time.time, time.sleep)
def __call__(self, func):
def wrapper(*args, **kwargs):
now = time.time()
# Remove old calls
while self.calls and self.calls[0] < now - self.period:
self.calls.popleft()
if len(self.calls) >= self.max_calls:
wait = self.calls[0] + self.period - now
time.sleep(wait)
self.calls.append(time.time())
return func(*args, **kwargs)
return wrapper
@RateLimiter(max_calls=3, period=1.0)
def api_call():
print(f"API call at {time.strftime('%H:%M:%S.%f')}")Custom Time Functions
Use virtual time for testing:
import sched
class VirtualClock:
def __init__(self):
self.time = 0
def get_time(self):
return self.time
def sleep(self, duration):
self.time += duration
clock = VirtualClock()
scheduler = sched.scheduler(clock.get_time, clock.sleep)
# Events run instantly with virtual time
scheduler.enter(100, 1, lambda: print("100 virtual seconds"))
scheduler.enter(200, 1, lambda: print("200 virtual seconds"))
scheduler.run() # Completes immediatelyWhen to Use sched
Use sched when:
- Simple delayed execution
- Event simulations
- Timing-based tests
- Single-threaded scheduling
Use alternatives when:
- Need threading →
threading.Timer - Async code →
asyncio.sleep - Background jobs →
APScheduler,Celery - Cron-style →
schedulelibrary
The sched module is simple and effective for basic scheduling needs.
React to this post: