Async Interrupt

1.2.2 · active · verified Wed Apr 15

async-interrupt is a Python library providing an `asyncio` context manager that raises an exception in the current task when a specified `asyncio.Future` becomes done. This allows for interrupting long-running or blocking async operations based on external conditions, effectively 'waiting for' a future to complete by interrupting the current task. The current version is 1.2.2, and it follows an infrequent, feature-driven release cadence.

Common errors

Warnings

Install

Imports

Quickstart

This quickstart demonstrates how to use `wait_for_async_interrupt` to interrupt an asynchronous operation. A `work_task` simulates long-running work. An `interrupt_future` is set after a short delay, which causes the `async with wait_for_async_interrupt` block to raise `asyncio.CancelledError`, effectively interrupting the main flow that is waiting for `work_task`.

import asyncio
from async_interrupt import wait_for_async_interrupt

async def _do_work():
    try:
        print("Worker: Starting long work...")
        await asyncio.sleep(5)  # Simulate long-running work
        print("Worker: Work finished normally")
    except asyncio.CancelledError:
        print("Worker: Work was interrupted!")

async def main():
    interrupt_future = asyncio.Future()
    
    work_task = asyncio.create_task(_do_work())

    # Simulate an external condition that finishes the future after 2 seconds
    async def trigger_interrupt_soon():
        await asyncio.sleep(2)
        print("Main: Signalling interrupt...")
        interrupt_future.set_result(None) # Complete the future to trigger interrupt

    asyncio.create_task(trigger_interrupt_soon())

    print("Main: Waiting for work or interrupt...")
    try:
        async with wait_for_async_interrupt(interrupt_future):
            await work_task # Wait for the work task to finish (or be interrupted)
    except asyncio.CancelledError:
        print("Main: Caught CancelledError due to future completion, as expected.")
    
    # Give the work_task a moment to process the cancellation
    await asyncio.sleep(0.1)
    
    if work_task.done():
        print(f"Main: Work task status: done, exception: {work_task.exception()}")
    else:
        print("Main: Work task is still running (this shouldn't happen if interrupt worked).")

if __name__ == "__main__":
    asyncio.run(main())

view raw JSON →