Python AsyncIO Run vs Run Until Complete

Python’s asyncio library is the built-in Python library for running code concurrently with the async/await keywords. The asyncio library is ideal for IO bound and structured network code. The difference between when to use the run command and the run_until_complete command with a loop is subtle but could have real implications for your code. In this post we’ll go over:

  • What is AsyncIO Run?
    • asyncio.run example
  • What is AsyncIO’s Run Until Complete?
    • asyncio.loop.run_until_complete example
  • A Commentary on AsyncIO loops
  • When to Use AsyncIO Run vs AsyncIO Loop’s Run Until Complete

AsyncIO Run – asyncio.run()

asyncio.run() is a high-level API in the asyncio library. It takes one required parameter, a coroutine, and one default named parameter, debug, which is set to False. The coroutine passed into asyncio.run() must be an async/await function. As I said earlier, this is a high-level API in the asyncio library, and under the hood it actually calls loop.run_until_complete().

This is the recommended entry point for asynchronous programs and should only be called once. The run function creates, executes, and closes a loop to run the run_until_complete function.

asyncio.run() example

We’ll use a simple example of waiting for 1 second using the asyncio.sleep() function. We’ll create an async test function that takes no parameters. All it does is print out the current time, await a sleep of 1, and then print out the current time again. Then we’ll use the async.run() function to test it.

import asyncio
import time
 
async def test():
    print(time.time())
    await asyncio.sleep(1)
    print(time.time())
 
asyncio.run(test())

It should print out something like this:

asyncio run sleep one second test
asyncio run sleep one second test

AsyncIO Run Until Complete – asyncio.loop.run_until_complete()

asyncio.loop.run_until_complete() is a low-level API in the asyncio native Python library. The function takes one parameter, a future object. A coroutine or task defined by the async/await keywords is a future object. That’s why we can call asyncio.loop.run_until_complete() with asyncio.run().

In order to use the asyncio.loop object’s run_until_complete() function, we need to actually have an asynio.loop object already instantiated or instantiate one on the call. 

asyncio.loop.run_until_complete() example

We will use the exact same function we used above in our example of asyncio.run(). We’ll create a function that prints the time, sleeps for a second, and then prints the time again. The only difference is how we’re going to run it. 

In this example, we’re going to use asyncio.new_event_loop() to create an async.loop object and then call run_until_complete() on the test() function. We should get the exact same result.

import asyncio
import time
 
async def test():
    print(time.time())
    await asyncio.sleep(1)
    print(time.time())
 
asyncio.new_event_loop().run_until_complete(test())

It should print out something like this:

asyncio run until complete sleep one second test
asyncio run until complete sleep one second test

Comment on AsyncIO Loops

Event loops are the core of asynchronous functions in Python. They run tasks, callbacks, network I/O, and subprocesses. Event loops are not meant to be used directly. They can be, but they shouldn’t be. They interact with asyncio’s low-level APIs. 

When to use asyncio.run vs asyncio.loop.run_until_complete

You should almost always use asyncio.run(). The only time you should use the run_until_complete() function over run() is if you need access to other low-level APIs. Modern applications are suggested to use asyncio.run()

Further Reading

I run this site to help you and others like you find cool projects and practice software skills. If this is helpful for you and you enjoy your ad free site, please help fund this site by donating below! If you can’t donate right now, please think of us next time.

Yujian Tang

2 thoughts on “Python AsyncIO Run vs Run Until Complete

Leave a Reply

%d bloggers like this: