Python: Sched for Automating Tasks in Python

Python version of Cron

Pravash
9 min readFeb 20, 2023
Python Sched

There are many python underdog libraries and scheduling is one of the them.

One of the most useful features of Python is the ability to schedule tasks to run at specific times or on a regular basis. For that Python provides a built-in module called sched. With the sched module, you can automate repetitive tasks, schedule reminders, or run scripts at specific times.

In this article, I will explore the concept of scheduling in Python and will also go through couple of examples on how to implement it.

Getting Started:

A scheduler is a tool that allows you to run a specific task at a specified time. This can be useful for a variety of applications, such as automating the execution of scripts, sending emails, or performing backups. In Python, the “sched” library provides a simple and easy-to-use interface for scheduling tasks.

The first step in using the sched module is to create an instance of the sched.scheduler class. This class is used to schedule and execute tasks, and provides several methods for adding, removing, and managing scheduled events.

import sched

scheduler = sched.scheduler()

In this example, I have created a new sched.scheduler object called scheduler.

Once we have a sched instance, we can use it to schedule tasks by calling the scheduler.enter method. This method takes several arguments, including the time at which the task should be executed, the priority of the task, and a function to be executed.

Here’s an example of how to schedule a simple task using the scheduler.enter method:

import sched
import time

def say_hello():
print("Hello, world!")

scheduler = sched.scheduler(time.time, time.sleep)

scheduler.enter(5, 1, say_hello, ())
scheduler.run()

In this example, I have defined a function called say_hello that prints "Hello, world!" to the console. Then created a new sched.scheduler object and passed in the time.time and time.sleep functions as arguments. These functions are used to calculate the time at which the task should be executed and to delay the program until that time.

Then called the scheduler.enter method, passing in the time at which the task should be executed (5 seconds from the current time), a priority of 1, the say_hello function to be executed, and an empty tuple of arguments.

Finally, called the scheduler.run method to start the scheduler and execute the scheduled task. The program will pause for 5 seconds before executing the say_hello function.

Lets Understand how it Works

The sched module in Python uses a priority queue to keep track of scheduled events. When we create a scheduler instance, it initializes an empty priority queue.

When we use the enter method to schedule an event, the scheduler adds the event to the priority queue. The event is added with a specific execution time and priority, which determines its position in the queue.

The scheduler then waits until the first event in the queue is due for execution. It does this by calling the sleep function, which blocks the program until the next event is due.

When an event is due for execution, the scheduler retrieves it from the priority queue and executes the function associated with the event. The scheduler then repeats this process for all events in the queue until there are no more events left.

If new events are added to the scheduler while it is running, they are added to the priority queue in order of their scheduled execution time. This ensures that events are executed in the correct order.

The scheduler also provides a way to cancel scheduled events using the cancel method. This method takes the event's reference as an argument and removes it from the priority queue if it is still pending.

Lets look at some of the implementation of sched in Python Program

Running Tasks Repeatedly:

In addition to scheduling tasks to run at specific times, the sched library also allows you to schedule tasks to run repeatedly.

To do this, you can use the enter or enterabs method in conjunction with a loop.

Here’s an example of how to schedule a task to run every 5 seconds:

import sched
import time

def say_hello():
print("Hello, world!")

scheduler = sched.scheduler(time.time, time.sleep)

def repeat_task():
scheduler.enter(5, 1, say_hello, ())
scheduler.enter(5, 1, repeat_task, ())

repeat_task()
scheduler.run()

In this example, I have defined a new function called repeat_task that uses the scheduler.enter method to schedule the say_hello function to be executed every 5 seconds. The repeat_task function then calls itself to reschedule the say_hello function again after 5 seconds.

Then it will call the repeat_task function to start the repeating task, followed by the scheduler.run method to execute the scheduled events

Using `enterabs` to Schedule a task to run at a specific time:

In addition to scheduling tasks to run after a delay or at a repeating interval, the sched module also allows you to schedule tasks to run at a specific time. You can use the scheduler.enterabs method to do this.

Here’s an example of how to schedule a task to run at a specific time:

import sched
import time

def say_hello():
print("Hello, world!")

scheduler = sched.scheduler(time.time, time.sleep)

# Schedule the task to run at a specific time
specific_time = time.time() + 5 # 5 seconds from now
scheduler.enterabs(specific_time, 1, say_hello, ())

scheduler.run()

In this example, I have defined a function called say_hello that prints "Hello, world!" to the console. Then created a new sched.scheduler object and pass in the time.time and time.sleep functions as arguments.

Then used the time.time() function to calculate a specific time 5 seconds from the current time, and pass this time to the scheduler.enterabs method along with a priority of 1, the say_hello function to be executed, and an empty tuple of arguments.

Finally, called the scheduler.run method to start the scheduler and execute the scheduled task. The program will pause until the specified time, at which point the say_hello function will be executed.

Scheduling Multiple Tasks:

In addition to scheduling individual tasks, you can also use the sched module to schedule multiple tasks. To do this, you can call the enter or enterabs methods multiple times with different task information.

Here’s an example of how to schedule two tasks to run at different intervals:

import sched
import time

def task_one():
print("Task One - Hello, world!")

def task_two():
print("Task Two - Hello, world!")

scheduler = sched.scheduler(time.time, time.sleep)

# Schedule task one to run after 2 seconds
scheduler.enter(2, 1, task_one, ())

# Schedule task two to run after 5 seconds
scheduler.enter(5, 1, task_two, ())

scheduler.run()

In this example, I have defined two functions, task_one and task_two, that both print "Hello, world!" to the console. Then created a new sched.scheduler object and pass in the time.time and time.sleep functions as arguments.

Then used the scheduler.enter method to schedule task_one to run after 2 seconds with a priority of 1, and task_two to run after 5 seconds with the same priority.

Finally, called the scheduler.run method to start the scheduler and execute the scheduled tasks. The program will pause for 2 seconds, execute task_one, pause for another 3 seconds, and then execute task_two.

Scheduling Tasks with different Priorities:

When scheduling tasks with the sched module, you can also assign different priorities to each task. Tasks with a lower priority number will be executed before tasks with a higher priority number.

Here’s an example of how to schedule two tasks with different priorities:

import sched
import time

def task_one():
print("Task One - Hello, world!")

def task_two():
print("Task Two - Hello, world!")

scheduler = sched.scheduler(time.time, time.sleep)

# Schedule task one with priority 1
scheduler.enter(2, 1, task_one, ())

# Schedule task two with priority 2
scheduler.enter(5, 2, task_two, ())

scheduler.run()

In this example, I defined two functions, task_one and task_two, that both print "Hello, world!" to the console. Then created a new sched.scheduler object and pass in the time.time and time.sleep functions as arguments.

Then used the scheduler.enter method to schedule task_one to run after 2 seconds with a priority of 1, and task_two to run after 5 seconds with a priority of 2.

Finally, I called the scheduler.run method to start the scheduler and execute the scheduled tasks. The program will pause for 2 seconds, execute task_one, pause for another 3 seconds, and then execute task_two.

Scheduling Tasks with a Cancel Method:

Sometimes it may be necessary to cancel a scheduled task before it is executed. The sched module provides a cancel method that can be used to remove a scheduled task from the scheduler.

Here’s an example of how to schedule a task and then cancel it:

import sched
import time

def task_one():
print("Task One - Hello, world!")

def task_two():
print("Task Two - Hello, world!")

scheduler = sched.scheduler(time.time, time.sleep)

# Schedule task one to run after 2 seconds
task_one_event = scheduler.enter(2, 1, task_one, ())

# Schedule task two to run after 5 seconds
task_two_event = scheduler.enter(5, 1, task_two, ())

# Cancel task one
scheduler.cancel(task_one_event)

scheduler.run()

In this example, I have defined two functions, task_one and task_two, that both print "Hello, world!" to the console. Then I create a new sched.scheduler object and pass in the time.time and time.sleep functions as arguments.

Then used the scheduler.enter method to schedule task_one to run after 2 seconds with a priority of 1, and task_two to run after 5 seconds with the same priority.

Next, I assigned the return value of the scheduler.enter method to the task_one_event and task_two_event variables. This allows us to reference the events later on.

Finally, I am calling the scheduler.cancel method and pass in the task_one_event variable to remove the task_one function from the scheduler. And then called scheduler.run to start the scheduler and execute the remaining scheduled tasks, which in this case is only task_two.

Running Backups:

Scheduling backups is a common task in many applications. In Python, we can use the sched module to schedule backup operations at a specific time or interval.

Here’s an example of how to use the sched module to schedule a backup operation:

import sched
import time
import shutil

def backup_files():
source = '/path/to/source/files'
destination = '/path/to/backup/location'
shutil.copytree(source, destination)

def schedule_backup():
# Create a new scheduler
scheduler = sched.scheduler(time.time, time.sleep)

# Schedule the backup to run at 1:00 AM every day
backup_time = time.strptime('01:00:00', '%H:%M:%S')
backup_event = scheduler.enterabs(time.mktime(backup_time), 1, backup_files, ())

# Start the scheduler
scheduler.run()

schedule_backup()

In this example, I have defined a function backup_files that copies a directory of files from a source location to a backup location. Then defined a function schedule_backup that creates a new sched.scheduler object and schedules the backup_files function to run every day at 1:00 AM.

To schedule the backup, first use the time.strptime function to convert the backup time from a string format of HH:MM:SS to a struct_time object. Then use the time.mktime function to convert the struct_time object to a UNIX timestamp, which is the format expected by the sched module.

Next, use the scheduler.enterabs method to schedule the backup_files function to run at the specified time with a priority of 1. Then call scheduler.run to start the scheduler and execute the scheduled backup.

Sending Emails:

In this example, I will show you how to use the sched module to schedule sending an email at a specific time.

import sched
import time
import smtplib
from email.mime.text import MIMEText

def send_email(subject, message, from_addr, to_addr, smtp_server):
# Create the email message
email = MIMEText(message)
email['Subject'] = subject
email['From'] = from_addr
email['To'] = to_addr

# Send the email
with smtplib.SMTP(smtp_server) as server:
server.send_message(email)

def send_scheduled_email(subject, message, from_addr, to_addr, smtp_server, scheduled_time):
# Create the scheduler
scheduler = sched.scheduler(time.time, time.sleep)

# Schedule the email
scheduler.enterabs(scheduled_time, 1, send_email, argument=(subject, message, from_addr, to_addr, smtp_server))

# Start the scheduler
scheduler.run()

subject = 'Test Email'
message = 'This is a test email'
from_addr = 'test@example.com'
to_addr = 'test@example.com'
smtp_server = 'smtp.test.com'

scheduled_time = time.time() + 60 # Schedule the email to be sent in 1 minute
send_scheduled_email(subject, message, from_addr, to_addr, smtp_server, scheduled_time)

In this example, I have defined a function send_scheduled_email that takes the subject, message, sender email address, recipient email address, SMTP server address, and scheduled time as arguments.

Then created a sched.scheduler object, which is used to schedule events. Here I have used the enterabs method of the scheduler to schedule the email to be sent at the specified time. The enterabs method takes a timestamp, a priority level, a function to call, and arguments to pass to the function as arguments.

When the scheduled time arrives, the scheduler calls the send_email function with the specified arguments.

We can then call the send_scheduled_email function with the email details and the scheduled time. In this example, we schedule the email to be sent in 1 minute from the current time.

NOTE:
You can schedule your tasks like calling a different script which performs some other functionalities like perform_etl, sql_load, running_batch_job, dataquality_check, report_generation, etc. with the below format using `subprocess`:

import sched
import time
import subprocess

s = sched.scheduler(time.time, time.sleep)

def your_function():
subprocess.call(['/path/to/your/script.py'])

# Schedule the job to run every Sunday at 2:00 AM
s.enterabs(time.mktime(time.strptime("2023–02–26 02:00:00", "%Y-%m-%d %H:%M:%S")), 1, cleaning_job)

# Start the scheduler
s.run()

In conclusion, the sched module in Python provides a simple and effective way to schedule tasks to run automatically.

Whether you need to run a task at a specific time or on a regular basis, the sched module has the tools to help you achieve your goals.

I believe this article helped you in getting the basic knowledge of how and where we can use sched.

There are other use cases of sched as I am not sure how extensively this is being used but yes, This scheduler runs in the background and manages a queue of events, executing them when their scheduled time arrives so you don’t have to worry about using separate threads or processes.

Connect with me on LinkedIn

--

--

Pravash

I am a passionate Data Engineer and Technology Enthusiast. Here I am using this platform to share my knowledge and experience on tech stacks.