py-asynclisted
Install: claude install-skill AllThingsSmitty/agent-skills
# Python Async Patterns
Python's asyncio runs on a single thread. Like Node.js, blocking that thread stalls every coroutine waiting to run. Most asyncio bugs are either blocking calls in async context or mismanaged coroutine scheduling.
## Never block the event loop
Any synchronous I/O or CPU-heavy work inside an `async` function blocks all other coroutines.
```python
# Bad: requests is synchronous — blocks the event loop entirely
async def fetch_user(user_id: str) -> dict:
response = requests.get(f'/users/{user_id}') # blocks
return response.json()
# Good: use an async HTTP client
import httpx
async def fetch_user(user_id: str) -> dict:
async with httpx.AsyncClient() as client:
response = await client.get(f'/users/{user_id}')
return response.json()
```
Common blocking calls to replace:
| Blocking | Async alternative |
|---|---|
| `requests` | `httpx` (async), `aiohttp` |
| `time.sleep` | `await asyncio.sleep` |
| `open()` / file I/O | `aiofiles` or `asyncio.to_thread` |
| `psycopg2` | `asyncpg`, `psycopg3` (async mode) |
For sync code you can't replace, run it in a thread:
```python
import asyncio
async def process():
result = await asyncio.to_thread(blocking_cpu_work, data)
return result
```
`asyncio.to_thread` (Python 3.9+) runs the function in a thread pool executor without blocking the event loop.
## Always `await` coroutines
Calling a coroutine without `await` creates a coroutine object but never runs it. Python will war