Async Programming in Python
Async IO lets you handle many I/O‑bound operations concurrently using async/await and an event loop.
Coroutines and the event loop
Define coroutines with async def and suspend with await. Use asyncio.run() to execute a top‑level coroutine.
import asyncio
async def fetch(n: int) -> str:
await asyncio.sleep(0.1) # simulate I/O
return f"result-{n}"
async def main() -> None:
print(await fetch(1))
asyncio.run(main())
Concurrency with tasks
Create tasks to run coroutines concurrently; gather waits for all and returns results.
async def main():
tasks = [asyncio.create_task(fetch(i)) for i in range(3)]
results = await asyncio.gather(*tasks)
print(results)
If any task fails, gather propagates the exception (configurable with return_exceptions=True).
Timeouts, cancellation, and shielding
Cancel tasks or apply timeouts to avoid hanging operations.
async def main():
try:
async with asyncio.timeout(1.0):
await fetch(42)
except TimeoutError:
print("timed out")
Cancel explicitly:
t = asyncio.create_task(fetch(1))
t.cancel()
try:
await t
except asyncio.CancelledError:
...
Async context managers and iterators
Use async with and async for when working with async resources/streams.
class A:
async def __aenter__(self): ...
async def __aexit__(self, exc_type, exc, tb): ...
async def consume(stream):
async for item in stream:
...
Threads and blocking calls
Never block the event loop with CPU‑bound work or blocking I/O. Offload to threads/processes when needed.
# Python 3.9+
await asyncio.to_thread(blocking_func, arg)
# or run_in_executor
loop = asyncio.get_running_loop()
await loop.run_in_executor(None, blocking_func)
Connection limits and backpressure
Use semaphores/queues to limit concurrency and buffer results safely.
sem = asyncio.Semaphore(10)
async def limited(task):
async with sem:
return await task
Best practices
- Prefer
asyncio.run()as the program entry point - Avoid blocking the loop; use
to_thread/executors for blocking work - Add timeouts and handle cancellations
- Bound concurrency with
Semaphore/Queue - Use libraries with native async support (HTTP, db drivers)
Summary
async/awaitcooperatively schedule I/O‑bound coroutines- Use tasks for concurrency; add timeouts and cancellation handling