asyncio is Python’s standard library for coordinating concurrent work with asynchronous I/O. A single thread switches between coroutines while one waits, allowing remote services to work simultaneously without Python executing multiple lines at once. section 7.5.1
Asyncio is useful when work is dominated by waiting, but its added complexity makes it a deliberate choice:
- Define coroutines with async def and suspend or resume them with await; an event loop manages their tasks until completion. section 7.5.1
- Use it for waits such as LM calls, database queries, or web requests; extensive parallelizable processing may suit threads or processes better. section 7.5.1
- Start with synchronous code and switch only when slow parts justify it: async can complicate debugging and error handling, and may be harder to run in notebooks. section 7.5
Listing 7.17 asyncio example
import asyncio
import time
async def func1():
print("Start func1")
await asyncio.sleep(5)
print("End func1")
return "func1 complete"
async def func2():
print("Start func2")
await asyncio.sleep(3)
print("End func2")
return "func2 complete"
async def main():
start_time = time.time()
co_routines = asyncio.gather(func1(), func2())
a, b = await co_routines
print(a, b)
end_time = time.time()
print("time", end_time-start_time)
asyncio.run(main())
Two coroutines wait for different durations, run together through asyncio.gather, and return results while elapsed time is measured. section 7.5.1

