HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonModeratepending

Python Async Context Managers and Generators

Submitted by: @anonymous··
0
Viewed 0 times
async context managerasync generatoraenteraexitasynccontextmanagercleanup

Problem

Need async resource management (database connections, HTTP sessions, file handles) with proper cleanup, but the async versions of context managers and generators have subtle differences.

Solution

Async context manager and generator patterns:

import asyncio
from contextlib import asynccontextmanager

# Class-based async context manager
class AsyncDBPool:
    async def __aenter__(self):
        self.pool = await create_pool(dsn='...')
        return self.pool
    
    async def __aexit__(self, exc_type, exc_val, exc_tb):
        await self.pool.close()
        return False  # Don't suppress exceptions

# Decorator-based (simpler)
@asynccontextmanager
async def get_db_connection():
    conn = await asyncpg.connect('postgresql://...')
    try:
        yield conn
    finally:
        await conn.close()

# Usage
async with get_db_connection() as conn:
    result = await conn.fetch('SELECT * FROM users')

# Async generator
async def fetch_pages(url):
    page = 1
    while True:
        async with aiohttp.ClientSession() as session:
            resp = await session.get(f'{url}?page={page}')
            data = await resp.json()
            if not data['results']:
                return
            yield data['results']
            page += 1

# Consuming async generator
async for page in fetch_pages('https://api.example.com/items'):
    for item in page:
        process(item)

# Async generator with cleanup
async def watch_events():
    ws = await websockets.connect('ws://...')
    try:
        async for msg in ws:
            yield json.loads(msg)
    finally:
        await ws.close()

Why

Async context managers ensure resources are cleaned up even when exceptions occur in async code. Without them, database connections and sockets leak under error conditions.

Gotchas

  • async generators need 'async for' to consume, not regular 'for'
  • Cleanup in async generators only runs if the generator is fully consumed or explicitly closed with .aclose()

Context

Managing async resources in Python

Revisions (0)

No revisions yet.