Last Updated on November 2, 2022
You can run an asyncio program by calling the asyncio.run() function.
In this tutorial, you will discover how to run an asyncio program in Python.
Let’s get started.
How to Run an Asyncio Program
An asyncio program can be run by calling the asyncio.run() function and passing in an instance of a coroutine.
The run() function will start the asyncio event loop and will schedule the coroutine provided as an argument.
This function runs the passed coroutine, taking care of managing the asyncio event loop, finalizing asynchronous generators, and closing the threadpool.
— Coroutines and Tasks
This can be achieved by creating the coroutine first, then passing it to the run() function.
For example:
1 2 3 4 5 |
... # create a coroutine coro = custom_coroutine() # start the asyncio program via the coroutine asyncio.run(coro) |
This can also be performed in one line by creating the coroutine instance in the call to the run() function.
For example:
1 2 3 |
... # start the asyncio program via the created coroutine asyncio.run(custom_coroutine()) |
The coroutine passed to the run() function is intended to start the asyncio program.
This function always creates a new event loop and closes it at the end. It should be used as a main entry point for asyncio programs, and should ideally only be called once.
— Coroutines and Tasks
The call to asyncio.run() will block the calling thread until the event loop is shut down.
If the provided coroutine takes an argument, it can be provided directly to the coroutine when it is created.
For example:
1 2 3 |
... # start the asyncio program with a coroutine that returns takes arguments asyncio.run(custom_coroutine(arg1, arg2, arg3)) |
If the provided coroutine passed to the run() function returns a value, it will in turn be returned from the run() function.
For example:
1 2 3 |
... # start the asyncio program with a coroutine that returns a value value = asyncio.run(custom_coroutine()) |
The coroutine passed to the run() function can only be executed once.
If it is passed again to a second call to asyncio.run(), a RuntimeError will be raised.
For example:
1 2 3 4 5 6 7 |
... # create a custom coroutine coro = custom_coro() # run the coroutine asyncio.run(coro) # run the coroutine again asyncio.run(coro) |
Finally, the asyncio.run() function cannot be called from within a coroutine. Doing so will result in a RuntimeError.
More specifically, only one asyncio event loop can be running within a Python thread.
This function cannot be called when another asyncio event loop is running in the same thread.
— Coroutines and Tasks
Now that we know how to start an asyncio program, let’s look at some worked examples.
Run loops using all CPUs, download your FREE book to learn how.
Example of Running an Asyncio Program
We can start an asyncio program by calling the asyncio.run() function and pass it the coroutine that is the entry point into our program.
The example below defines a custom coroutine that takes an argument and prints it. The asyncio program is then executed by creating an instance of the coroutine with an argument and passing it to the run() function.
1 2 3 4 5 6 7 8 9 10 11 |
# SuperFastPython.com # example of starting an asyncio program import asyncio # custom coroutine async def custom_coro(message): # report the message print(message) # create and execute coroutine asyncio.run(custom_coro('hello world')) |
Running the example first creates the coroutine with an argument.
The asyncio.run() function is then called and passed the coroutine. The asyncio event loop runs, executes the coroutine and the message is reported.
This highlights the most common way to start an asyncio program.
1 |
hello world |
Example of Running an Asyncio Program With a Return Value
The coroutine passed to the asyncio.run() function to start the asyncio program can return a value.
The value will be returned from the coroutine and then from the run() function.
The example below defines a custom coroutine that takes an argument, then returns a modified version of the argument back to the main thread of the program.
1 2 3 4 5 6 7 8 9 10 11 12 |
# SuperFastPython.com # example of starting an asyncio program that returns a value import asyncio # custom coroutine async def custom_coro(message): # return a value return f'Got: {message}' # create and execute coroutine result = asyncio.run(custom_coro('hello world')) print(result) |
Running the example first creates the coroutine with an argument and passes it to the run() function to start the asyncio event loop.
The coroutine is then executed, returning a string that contains the provided argument.
The run() function then returns the return value from the coroutine, which is then finally reported in the main thread.
1 |
Got: hello world |
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 Coroutine Cannot Be Run Twice
A coroutine cannot be used to start two asyncio programs.
If a coroutine is used more than once, a RuntimeError is raised.
The example below creates a coroutine and uses it to start an asyncio program. The same coroutine is then passed to the run() function again to start a second asyncio program.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
# SuperFastPython.com # example of starting an asyncio program import asyncio # custom coroutine async def custom_coro(message): # report the message print(message) # create a custom coroutine coro = custom_coro('hello world') # run the coroutine asyncio.run(coro) # run the coroutine again asyncio.run(coro) |
Running the example first creates the coroutine and passes it an argument.
The coroutine is then used to start an asyncio event loop and is executed, printing the provided message.
The same coroutine is then used to start a second asyncio event loop. This fails and a RuntimeError is raised indicating that a coroutine cannot be reused.
1 2 3 4 |
hello world Traceback (most recent call last): ... RuntimeError: cannot reuse already awaited coroutine |
Overwhelmed by the python concurrency APIs?
Find relief, download my FREE Python Concurrency Mind Maps
Example Where run() Cannot Be Called Twice
The asyncio.run() function can only be run once within a Python thread.
Attempting to call the run() method again once it is already running, such as from within a coroutine, will result in a RuntimeError.
The example below creates a coroutine and uses it to start the asyncio event loop. The coroutine then creates a second coroutine and calls the run() function in an attempt to start a second asyncio event loop.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
# SuperFastPython.com # example of calling run from within a coroutine import asyncio # example of defining another coroutine async def another_custom(): print('Another coroutine') # custom coroutine async def custom_coro(message): # report the message print(message) # create another coroutine another_coro = another_custom() # attempt to run the coroutine asyncio.run(another_coro) # create and execute coroutine asyncio.run(custom_coro('hello world')) |
Running the example first creates a coroutine and passes it an argument. The coroutine is then used to start the asyncio event loop.
The coroutine then reports a message and creates a second coroutine. It then calls the run() function and passes it the second coroutine in an attempt to start a second asyncio event loop.
This fails and results in a RuntimeException.
The program terminates. Because the second coroutine instance does not get a chance to execute, a RuntimeWarning is raised.
1 2 3 4 5 |
hello world Traceback (most recent call last): .... RuntimeError: asyncio.run() cannot be called from a running event loop sys:1: RuntimeWarning: coroutine 'another_custom' was never awaited |
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 an asyncio program in Python.
Do you have any questions?
Ask your questions in the comments below and I will do my best to answer.
Photo by Felipe Simo on Unsplash
Sadegh says
I expect this code to do five prints at the same time. Can you tell me what did I get wrong?
async def foo():
print('----called foo-----')
await asyncio.sleep(2)
async def async_bar():
for _ inrange(5):
awaitfoo()
asyncio.run(async_bar())
Jason Brownlee says
No, in this case you are running five calls sequentially.
To run five calls concurrently, you would do something like this:
You can learn more about asyncio.gather() here:
https://superfastpython.com/asyncio-gather/