Python asyncio Future

Summary: in this tutorial, you’ll learn about Python asyncio future objects and understand how they work.

Introduction to the Python asyncio future

A future is an object that returns a value later in the future but not now. Typically, a future object is the result of an asynchronous operation.

For example, you may call an API from a remote server and expect to receive the result later. The API call may return a future object so that you can await it.

To create a future object, you use the Future class from the asyncio package. Consider the following example:

import asyncio
from asyncio import Future


async def main():
    my_future = Future()
    print(my_future.done())  # False

    my_future.set_result('Bright')

    print(my_future.done())  # True

    print(my_future.result())


asyncio.run(main())Code language: Python (python)

How it works.

First, import Future class from the asyncio library:

from asyncio import FutureCode language: Python (python)

Next, create a new Future object in the main() coroutine:

my_future = Future()Code language: Python (python)

A newly created future doesn’t have any value because it doesn’t exist yet. In this state, the future is considered incomplete, unresolved, or not done.

Then, call the done() method to check the status of the future object:

print(my_future.done())  # FalseCode language: Python (python)

It returns False.

After that, set a value for the future object by calling the set_result() method:

my_future.set_result('Bright')Code language: Python (python)

Once you set the value, the future is done. Calling the done() method of the future object in this stage returns True:

print(my_future.done())  # TrueCode language: Python (python)

Finally, get the result from the future object by calling its result() method:

print(my_future.result())Code language: Python (python)

Using Python asyncio future with await

When you use the await keyword with a future, you pause the future until it returns a value. The following example shows how to use the future with await keyword:

from asyncio import Future
import asyncio


async def plan(my_future):
    print('Planning my future...')
    await asyncio.sleep(1)
    my_future.set_result('Bright')


def create() -> Future:
    my_future = Future()
    asyncio.create_task(plan(my_future))
    return my_future


async def main():
    my_future = create()
    result = await my_future

    print(result)


asyncio.run(main())Code language: Python (python)

Output:

Planning my future...
BrightCode language: Python (python)

How it works.

First, define a coroutine that accepts a future and sets its value after 1 second:

async def plan(my_future: Future):
    print('Planning my future...')
    await asyncio.sleep(1)
    my_future.set_result('Bright')Code language: Python (python)

Second, define a create() function that schedules the plan() coroutine as a task and returns a future object:

def create() -> Future:
    my_future = Future()
    asyncio.create_task(plan(my_future))
    return my_futureCode language: Python (python)

Third, call the create() function that returns a future, use the await keyword to wait for the future to return a result, and display it:

async def main():
    my_future = create()
    result = await my_future

    print(result)Code language: Python (python)

In practice, you’ll rarely need to create Future objects directly. However, you’ll use the Future objects returned from API. Therefore, it’s important to understand how the Future works.

Futures, Tasks, and Coroutines

The following class hierarchy shows the relationships between Coroutine, Future, and Task:

In this class hierarchy, Courtine, Future, and Task are subclasses of the Awaitable abstract class.

The Awaitable class has an abstract method __await__(). Any class that has the implementation of the __await__() method can be used with the await keyword. And the objects of classes that can be used with the await keyword are called awaitables.

Summary

  • A future is an object that returns a value in the future, not now.
  • Future, Coroutine, and Task are awaitable and their objects can be used with the await keyword.
Did you find this tutorial helpful ?