Python asyncio: Run a task at a certain time every day (2 examples)

Updated: August 4, 2023 By: Wolf Post a comment

By using Python, you can build a small (or large) system that can automatically do some monotonous and repetitive tasks at a certain time every day (maybe at midnight, when you’re sleeping), such as backing up files or databases, sending marketing emails, fetching new data from the internet, etc. This concise, example-based article will show you how to efficiently do so by making use of the asyncio module, which allows you to write asynchronous code using the async/await syntax.

Running a task at a certain time every day

To perform a task at a certain time every day, you need to use the asyncio.sleep() function, which suspends the execution of a coroutine for a given number of seconds. You can use this function to calculate the delay between the current time and the desired time, and then await it before doing your job. For instance, if you want to run a task at 00:30 every day, you can do as follows:

# SlingAcademy.com
# This code uses Python 3.11.4

import asyncio
import datetime


# This coroutine will run a coroutine at a specific time
async def run_at(time, coro):
    # Get the current timeba
    now = datetime.datetime.now()

    # Calculate the delay until the next occurrence of time
    delay = ((time - now) % datetime.timedelta(days=1)).total_seconds()

    # Sleep until then
    await asyncio.sleep(delay)

    # Run the coroutine
    return await coro


# This is the coroutine that will be run every day
async def good_night():
    print("Good night!")
    # Do other stuff if you want


async def main():
    # Create a datetime object for 00:30
    time = datetime.datetime.combine(datetime.date.today(), datetime.time(0, 30))

    # Run good_night at 00:30 every day
    while True:
        await run_at(time, good_night())


# Run the main coroutine
asyncio.run(main())

This code will print “Good night!” at 0:30 every night. It assumes that your computer’s clock is accurate. In the next section of this article, we will build a more complex automation program.

Running multiple tasks at different times every day

In case you want to run multiple tasks at different times every day, you can use the asyncio.gather() function, which takes a list of coroutines or tasks and returns a future that represents their aggregated result. You can then await this future in your main coroutine.

The example below simulates an automation program that sends an email at 10:00 AM and backup data at 11:00 AM every day (the run_at() function you’ve seen in the previous example will be reused):

# SlingAcademy.com
# This code uses Python 3.11.4

import asyncio
import datetime


# This coroutine will run a coroutine at a specific time
# You've seen this before. Do you know where?
async def run_at(time, coro):
    # Get the current time
    now = datetime.datetime.now()

    # Calculate the delay until the next occurrence of time
    delay = ((time - now) % datetime.timedelta(days=1)).total_seconds()

    # Sleep until then
    await asyncio.sleep(delay)

    # Run the coroutine
    return await coro


async def send_email():
    print("The system is sending an email to [email protected]")
    await asyncio.sleep(1)
    print("The email has been sent successfully!")
    # Your code to send an email goes here


async def backup_data():
    print("The system is backing up the data")
    await asyncio.sleep(5)
    print("The data has been backed up successfully!")
    # Your code to backup the data goes here


async def main():
    # Create datetime objects for 10:00 AM and 11:00 AM
    time1 = datetime.datetime.combine(datetime.date.today(), datetime.time(10))
    time2 = datetime.datetime.combine(datetime.date.today(), datetime.time(11))

    # Run send_email at 10:00 AM and backup_data at 11:00 AM every day
    while True:
        await asyncio.gather(
            run_at(time1, send_email()), 
            run_at(time2, backup_data())
        )


# Run the main coroutine
asyncio.run(main())

Conclusion

The asyncio module helps you execute multiple tasks concurrently without blocking the main thread of execution. Thus, can improve the performance and responsiveness of your program, especially when dealing with IO-bound operations such as network requests, file operations, or database queries. In this article, we used asyncio to build two programs that can rescue us from tiresome stuff. The code is simple, but the core idea will remain unchanged even in large applications.

This tutorial ends here. If you find something outdated or incorrect, please let me know by leaving a comment. Happy coding & have a nice day!