Python › Async Generators & Async Context Managers

How do you write an async context manager more concisely using @contextlib.asynccontextmanager?

Intermediate

Answer

asynccontextmanager decorates a single async generator function: code before the 'yield' runs as __aenter__, the yielded value becomes the 'as' target, and code after 'yield' (typically in a try/finally) runs as __aexit__ — avoiding the need to write a full class with both dunder methods.
from contextlib import asynccontextmanager

@asynccontextmanager
async def async_connection():
    conn = await connect()
    try:
        yield conn
    finally:
        await conn.close()

async def main():
    async with async_connection() as conn:
        await conn.query("SELECT 1")
Real-world example Writing a lightweight, function-based async resource manager without the boilerplate of a full __aenter__/__aexit__ class.

Common follow-ups: How does this asynccontextmanager decorator compare to the synchronous @contextlib.contextmanager?