Async/Await in Practice
Asyncio Core
Async/Await Crash Course
Coroutines let you write sequential-looking code that cooperatively multitasks.
Structure
import asyncio
async def fetch_order(order_id):
await asyncio.sleep(0.1)
return {'id': order_id}
async def main():
order = await fetch_order('123')
print(order)
asyncio.run(main())
asyncdeclares coroutines;awaitpauses until awaited tasks complete.- Use
asyncio.runto bootstrap top-level coroutines.
Gathering tasks
async def main():
orders = await asyncio.gather(
fetch_order('123'),
fetch_order('456'),
fetch_order('789'),
return_exceptions=True,
)
print(orders)
asyncio.run(main())
asyncio.gatherwaits for all tasks; passreturn_exceptions=Trueto collect exceptions as results instead of raising them immediately.asyncio.create_taskschedules background work; keep references so you can await or cancel later.
Task groups (Python 3.11+)
async def main():
async with asyncio.TaskGroup() as tg:
t1 = tg.create_task(fetch_order('123'))
t2 = tg.create_task(fetch_order('456'))
print(t1.result(), t2.result())
asyncio.run(main())
asyncio.TaskGroupis the recommended structured-concurrency approach for new code: theasync withblock waits for all tasks, and if one fails the siblings are cancelled and the failures are raised as anExceptionGroup.- Prefer it over bare
gatherwhen tasks should succeed or fail together.
Error handling
- Wrap awaits in try/except just like synchronous code.
- Use
asyncio.wait_forto enforce deadlines; on Python 3.11+ prefer theasync with asyncio.timeout(10):context manager. Since 3.11,asyncio.TimeoutErroris an alias of the builtinTimeoutError. - Cancel tasks with
task.cancel()to clean up when shutting down.