You can wrap a coroutine in an asyncio.Task which will schedule it for later execution.
This allows you to run coroutines in the background that do not block the caller.
In this tutorial, you will discover how to run a coroutine in the background as an asyncio task.
Let’s get started.
Need to Run a Background Coroutine
When running a coroutine from a coroutine within asyncio, it blocks the caller.
That is, it suspends the caller until the other coroutine is complete.
For example:
1 2 3 |
... # suspend and wait for the coroutine to complete await other_coroutine() |
We may need to execute a coroutine in the background.
That is, schedule the coroutine for execution and have it run as soon as it is able, but not explicitly suspend the calling coroutine.
How can we run a coroutine in the background in asyncio?
Run loops using all CPUs, download your FREE book to learn how.
How to Run a Background Coroutine
We can run a coroutine in the background by wrapping it in an asyncio.Task object.
This can be achieved by calling the asyncio.create_task() function and passing it the coroutine.
The coroutine will be wrapped in a Task object and will be scheduled for execution. The task object will be returned and the caller will not suspend.
For example:
1 2 3 |
... # schedule the task for execution task = asyncio.create_task(other_coroutine()) |
You can learn more about how to create tasks in the tutorial:
The task will not begin executing until at least the current coroutine is suspended, for any reason.
We can help things along by suspending for a moment to allow the task to start running.
This can be achieved by sleeping for zero seconds.
For example:
1 2 3 |
... # suspend for a moment to allow the task to start running await asyncio.sleep(0) |
This will suspend the caller only for a brief moment and allow the ask an opportunity to run.
This is not required as the caller may suspend at some future time or terminate as part of normal execution.
You can learn more about sleeping in the tutorial:
We may also await the task directly once the caller has run out of things to do.
For example:
1 2 3 |
... # wait for the task to complete await task |
Now that we know how to run a coroutine in the background as a task, let’s look at some worked examples.
Example of Running a Foreground Task
Before we look at how to run a coroutine as a task in the background, let’s review how we might run it in the foreground.
That is, we can call a coroutine directly and have it suspend the caller.
The example below defines a custom coroutine and calls that coroutine from the main coroutine.
The main coroutine will block until the called coroutine is complete.
Note, we are not calling the coroutine per se, we are scheduling it for executing and waiting for it to complete, e.g. await it.
The complete example is listed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
# SuperFastPython.com # example of running an asyncio coroutine in the foreground import asyncio # custom coroutine async def custom_coro(): # report a message print('Coroutine is running') # simulate some long running task await asyncio.sleep(5) # report another message print('Coroutine is done') # main coroutine async def main(): # create the coroutine coro = custom_coro() # run the coroutine in the foreground await coro # run the asyncio program asyncio.run(main()) |
Running the example first creates the main() coroutine and uses it as the entry point for the asyncio program.
The main() coroutine runs and creates the custom_coro(). It then awaits this new coroutine.
This suspends the main() coroutine and schedules the custom_coro() coroutine.
The custom_coro() runs, reports a message, sleeps, then reports a final message before terminating.
The main() coroutine then resumes and closes the program.
This highlights how a coroutine can be executed in a way that blocks the caller, e.g. in the foreground of a coroutine.
1 2 |
Coroutine is running Coroutine is done |
Next, let’s explore how we might run a coroutine in the background as a task.
Free Python Asyncio Course
Download your FREE Asyncio PDF cheat sheet and get BONUS access to my free 7-day crash course on the Asyncio API.
Discover how to use the Python asyncio module including how to define, create, and run new coroutines and how to use non-blocking I/O.
Example of Running a Background Task
We can run a coroutine in the background as a task.
Specifically, we can have the coroutine wrapped in an asyncio.Task and have it scheduled for execution as soon as it can.
The example below creates a custom coroutine from the main coroutine and schedules it for execution as a task. It then sleeps for a moment to allow the task to begin executing, then sleeps for a longer time to simulate doing other work.
The complete example of running a coroutine as a background task is listed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
# SuperFastPython.com # example of running an asyncio coroutine in the background import asyncio # custom coroutine async def custom_coro(): # report a message print('Coroutine is running') # simulate some long running task await asyncio.sleep(5) # report another message print('Coroutine is done') # main coroutine async def main(): # create the coroutine coro = custom_coro() # schedule the coroutine to run in the background task = asyncio.create_task(coro) # allow the task to run await asyncio.sleep(0) # report a message print('Main doing other stuff...') # simulate continue on with other things await asyncio.sleep(5) # run the asyncio program asyncio.run(main()) |
Running the example first creates the main() coroutine and uses it as the entry point for the asyncio program.
The main() coroutine runs and creates the custom_coro().
It then wraps the coroutine in an asyncio.Task and schedules it for execution.
The main() coroutine then sleeps for zero seconds. This suspends the caller and allows the scheduled coroutine to execute.
The custom_coro() coroutine executes, reporting a message and then suspending with a sleep.
The main() coroutine resumes, reports a message then sleeps to simulate doing other work.
The custom_coro() completes its sleep, resumes, reports a final message then terminates.
The main() coroutine finishes its sleep, resumes and the program is terminated.
This example highlights how we can run a coroutine in the background as a task.
1 2 3 |
Coroutine is running Main doing other stuff... Coroutine is done |
Overwhelmed by the python concurrency APIs?
Find relief, download my FREE Python Concurrency Mind Maps
Further Reading
This section provides additional resources that you may find helpful.
Python Asyncio Books
- Python Asyncio Mastery, Jason Brownlee (my book!)
- Python Asyncio Jump-Start, Jason Brownlee.
- Python Asyncio Interview Questions, Jason Brownlee.
- Asyncio Module API Cheat Sheet
I also recommend the following books:
- Python Concurrency with asyncio, Matthew Fowler, 2022.
- Using Asyncio in Python, Caleb Hattingh, 2020.
- asyncio Recipes, Mohamed Mustapha Tahrioui, 2019.
Guides
APIs
- asyncio — Asynchronous I/O
- Asyncio Coroutines and Tasks
- Asyncio Streams
- Asyncio Subprocesses
- Asyncio Queues
- Asyncio Synchronization Primitives
References
Takeaways
You now know how to run a coroutine in the background as an asyncio task.
Do you have any questions?
Ask your questions in the comments below and I will do my best to answer.
Photo by Vincent Guzman on Unsplash
Do you have any questions?