Timeouts

asyncio · Essentials · 8 min

Network calls can hang forever; every real client needs a timeout.

Since Python 3.11, the preferred tool is the async context manager asyncio.timeout(delay). Everything inside the async with block must finish within delay seconds. If it doesn't, the current task is cancelled at its current await, and on leaving the block the cancellation is converted into a TimeoutError (the built-in; asyncio.TimeoutError is an alias).

async with asyncio.timeout(2):
    data = await fetch()

The block can contain several awaits, and they share one deadline. asyncio.timeout_at(when) takes an absolute loop time instead, and the returned object's reschedule() lets you extend the deadline. Pass None for no timeout.

asyncio.wait_for(aw, timeout) is the older, single-awaitable form; since 3.12 it is implemented on top of timeout(). It wraps the awaitable, cancels it on timeout and raises TimeoutError.

Cancellation means cleanup in finally blocks of the cancelled code runs. Catch TimeoutError outside the async with block, not inside it, because inside the block you would be catching the cancellation itself.

Example

import asyncio

async def slow():
    try:
        await asyncio.sleep(10)
    finally:
        print("slow: cleaning up")        # runs on cancellation

async def main():
    try:
        async with asyncio.timeout(0.2):
            await slow()
    except TimeoutError:
        print("timed out")
    print(await asyncio.wait_for(asyncio.sleep(0.01, "fast"), timeout=1))

asyncio.run(main())
# slow: cleaning up
# timed out
# fast

Remember

  • async with asyncio.timeout(s): sets one deadline for a block
  • On expiry the work is cancelled and TimeoutError is raised
  • wait_for(aw, timeout) is the single-awaitable form

Watch out for

  • Catching TimeoutError inside the timeout block; catch it around the async with.

Check yourself

  1. What exception do you catch after an asyncio.timeout(1) block expires (Python 3.11+)?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: docs.python.org/3/library/asyncio-task.html#timeouts