Python Async
- Use
async defonly when the function awaits IO or coordinates other coroutines, not for ordinary CPU work - Call async functions with
await, never by dropping the coroutine on the floor - Run the loop at the edge with
asyncio.run(...)inmain, not from inside library code - Never call blocking IO (
time.sleep,openon a slow path, sync HTTP or DB clients) from async code; use the async equivalent orasyncio.to_thread - Pass a timeout on every wait that can hang:
asyncio.wait_for, client timeouts, lock timeouts - Cancel and await cleanup in
finallyor withTaskGroup/async with, do not leak tasks - Do not mix
trio,anyioand rawasyncioin one project; follow whatever the codebase already uses
Good:
async def fetch_all(client: httpx.AsyncClient, urls: list[str]) -> list[bytes]: async with asyncio.TaskGroup() as tg: tasks = [tg.create_task(client.get(url)) for url in urls] return [t.result().content for t in tasks]Bad:
async def fetch_all(urls: list[str]) -> list[bytes]: return [httpx.get(url).content for url in urls]