Python schedule

Table of Contents

Introduction

If you are wondering how to schedule a task in python, you should definitely consider using the Python package schedule.
Schedule is a Python package that offers a set of easy-to-use APIs for scheduling tasks (functions).
It is lightweight and requires no other external dependencies.

The next sections will show you how to install this Python package and how to best use it!
Don’t worry, you will also find the link to GitHub with a practical example ready to download and use!

Schedule – Python package

Suppose you are developing a program that requires a certain activity or function to run every 10 minutes.
The Python schedule library was created for these uses!

As mentioned in the official documentation, there are cases where it is better not to use this library, that is, if you need:

  • Job persistence (remember schedule between restarts)
  • Exact timing (sub-second precision execution)
  • Concurrent execution (multiple threads)
  • Localization (time zones, workdays or holidays)

If your case does not fall within those mentioned above well, let’s not waste any more time and proceed with the installation!

How to install Python schedule

Before proceeding with the installation you need to know that the latest version of schedule is compatible with Python> 3.6.
If you are using a lower version you will need to install schedule to version 0.6.0.
Don’t worry, we will see both cases.

Since we are installing an external package, I recommend that you create a virtualenv.
If you don’t know how to do it, here there is a post with the procedure on how to create a virtualenv.

Regardless of whether you have created the virtualenv or not (I recommend it) you can install schedule with the following command:

pip install schedule

If you need to install a specific version, for example 0.6.0, use this command:

pip install schedule==0.6.0

Feel free to replace 0.6.0 with the version you need.

How to use Python schedule

After installing the python package schedule, the first thing you will need to do is import it with this statement:

import schedule

Now suppose we want to execute a function every 20 seconds.
You can achieve this simple task with the code below:

from datetime import datetime
import schedule
def task_for_seconds():
    now = datetime.now()
    print("This task runs every 20 seconds! ({})".format(now.strftime("%d/%m/%Y %H:%M:%S")))
# get starting time
now = datetime.now()
print("Script starting at {}".format(now.strftime("%d/%m/%Y %H:%M:%S")))
# schedule all tasks
while True:
    schedule.run_pending()

Let’s briefly explain the above piece of code.

The first two lines of code are used to import the libraries we need that is datetime and obviously schedule.
Next we declared a function called task_for_seconds whose job is simply to print a message with the current time on the screen.
Finally, we have another print that will be executed only once at program startup which indicates the start time and last but not least, an infinite while loop to execute the scheduled tasks.

Running the code we have the following output. Obviously partial as the program does not have an end.

Python schedule - run every 2 seconds output
Python schedule – run every 2 seconds output

In the same way we can modify the code above so as to add different tasks to be executed at different times.
Let’s try adding these functions and scheduling them:

def task_for_seconds():
    now = datetime.now()
    print("This task runs every 20 seconds! ({})".format(now.strftime("%d/%m/%Y %H:%M:%S")))

def task_for_minutes():
    now = datetime.now()
    print("This task runs every minute! ({})".format(now.strftime("%d/%m/%Y %H:%M:%S")))

def task_for_minutes_at_ten():
    now = datetime.now()
    print("This task runs every minute at 10 secs! ({})".format(now.strftime("%d/%m/%Y %H:%M:%S")))

def task_for_hours():
    now = datetime.now()
    print("This task runs every 2 hours! ({})".format(now.strftime("%d/%m/%Y %H:%M:%S")))

def task_for_days():
    now = datetime.now()
    print("This task runs every 5 days! ({})".format(now.strftime("%d/%m/%Y %H:%M:%S")))

# Run task every 20 seconds
schedule.every(20).seconds.do(task_for_seconds)
# Run task every minute
schedule.every().minutes.do(task_for_minutes)
# Run task every 2 hours
schedule.every(2).hours.do(task_for_hours)
# Run task every 5 days
schedule.every(5).days.do(task_for_days)
# Run task every minute at the 10rd second
schedule.every().minute.at(":10").do(task_for_minutes_at_ten)

As you can see from the example above it is possible to combine the use of every() and at() to better schedule the task.
The output of the code shown above is this:

Python schedule output
Python schedule output

All the code we’ve seen is available at this GitHub repository!
I recommend that you download it and do some testing to get used to the schedule package.

How to use Python schedule with decorators

In the previous section we have scheduled some simple tasks every 20 seconds, every minute and other combinations.
Now I want to show you how it is possible to execute the same code by scheduling tasks by decorating functions.
Here is the modified code:

from datetime import datetime
from schedule import every, repeat, run_pending

@repeat(every(20).seconds)
def task_for_seconds():
    now = datetime.now()
    print("This task runs every 20 seconds! ({})".format(now.strftime("%d/%m/%Y %H:%M:%S")))

@repeat(every().minutes)
def task_for_minutes():
    now = datetime.now()
    print("This task runs every minute! ({})".format(now.strftime("%d/%m/%Y %H:%M:%S")))

@repeat(every().minute.at(":10"))
def task_for_minutes_at_ten():
    now = datetime.now()
    print("This task runs every minute at 10 secs! ({})".format(now.strftime("%d/%m/%Y %H:%M:%S")))

@repeat(every(2).hours)
def task_for_hours():
    now = datetime.now()
    print("This task runs every 2 hours! ({})".format(now.strftime("%d/%m/%Y %H:%M:%S")))

@repeat(every(5).days)
def task_for_days():
    now = datetime.now()
    print("This task runs every 5 days! ({})".format(now.strftime("%d/%m/%Y %H:%M:%S")))

now = datetime.now()
print("Script starting at {}".format(now.strftime("%d/%m/%Y %H:%M:%S")))
# schedule all tasks
while True:
    run_pending()

As you may have noticed, each function has a repeat decorator in which you specify when you want to execute the task.
I point out that the syntax is practically identical as well as the purpose.
You choose the method you prefer based on your code.

Also in this case, a GitHub repository is present.

Python schedule – Other options

In the previous examples we have seen how to schedule new tasks in Python.
The library allows us to do other things with tasks such as deleting them, returning active tasks and much more.

The list below summarizes all these features (also explained in the official documentation):

  • run_pending(): run all jobs that are scheduled to run.
  • run_all(delay_seconds: int = 0): run all jobs regardless if they are scheduled to run or not.
  • get_jobs(tag: Optional[collections.abc.Hashable] = None): gets scheduled jobs marked with the given tag, or all jobs if tag is omitted.
  • clear(tag: Optional[collections.abc.Hashable] = None): deletes scheduled jobs marked with the given tag, or all jobs if tag is omitted.
  • cancel_job(job: schedule.Job): delete a scheduled job.
  • every(interval: int = 1): schedule a new periodic job.
  • next_run: datetime when the next job should run.
  • idle_seconds: returns the number of seconds until next_run or None if no jobs are scheduled.

Python schedule offers several units of time beyond those seen in the examples, here is the complete list.

  • second
  • seconds
  • minute
  • minutes
  • hour
  • hours
  • day
  • days
  • week
  • weeks
  • monday
  • tuesday
  • wednesday
  • thursday
  • friday
  • saturday
  • sunday

At each unit of time it is also possible to chain other functions to specialize the execution of the task.

  • at(time_str): Specify a particular time that the job should be run at.
  • to(latest: int): schedule the job to run at an irregular (randomized) interval.
  • until(until_time: Union[datetime.datetime, datetime.timedelta, datetime.time, str]): schedule job to run until the specified moment.
  • do(job_func: Callable, *args, **kwargs): specifies the job_func that should be called every time the job runs.
  • should_run: returns True if the job should be run now.
  • run(): run the job and immediately reschedule it.

Conclusion

Here we are at the end of this post, as always I hope this article will be useful to you and that now you know everything about the Python package schedule.
If you find that something is unclear or you have a problem that you don’t know how to solve, leave me a comment below and I will try to help you as soon as possible.

If this topic is clear to you, take a look at the latest posts!

Leave a Comment

Your email address will not be published. Required fields are marked *