{"id":7194,"library":"duet","title":"Duet Async Library","description":"Duet is a simple future-based async library for Python, version 0.2.9. It takes inspiration from the `trio` library's structured concurrency but primarily relies on the standard `concurrent.futures.Future` interface for parallelism, allowing `async/await` coroutines to interact with these futures. A distinctive feature of Duet is its re-entrancy, permitting multiple calls to `duet.run()` within a single asynchronous context, which can simplify the incremental refactoring of synchronous codebases to asynchronous ones. The library is actively maintained with a steady release cadence for bug fixes and minor improvements.","status":"active","version":"0.2.9","language":"python","source_language":"en","source_url":"https://github.com/google/duet","tags":["async","concurrency","futures","structured-concurrency","event-loop"],"install":[{"cmd":"pip install duet","lang":"bash","label":"Install with pip"}],"dependencies":[{"reason":"Required Python version for the library.","package":"python","optional":false}],"imports":[{"note":"The primary entry point to execute an async function with Duet.","symbol":"run","correct":"from duet import run"},{"note":"Used to wrap standard `concurrent.futures.Future` objects to make them awaitable within Duet's async context.","symbol":"AwaitableFuture","correct":"from duet import AwaitableFuture"}],"quickstart":{"code":"import concurrent.futures\nimport time\nimport duet\n\ndef long_running_sync_task(value):\n    \"\"\"A blocking synchronous task.\"\"\"\n    time.sleep(0.1) # Simulate work\n    return f\"Processed {value}\"\n\nasync def async_wrapper(future: concurrent.futures.Future):\n    \"\"\"Wraps a concurrent.futures.Future to be awaitable in Duet.\"\"\"\n    return await duet.AwaitableFuture(future)\n\nasync def main():\n    print(\"Starting Duet example...\")\n    \n    # Example 1: Running a synchronous task in a thread pool executor\n    with concurrent.futures.ThreadPoolExecutor() as executor:\n        future = executor.submit(long_running_sync_task, \"data_item_A\")\n        result_a = await async_wrapper(future)\n        print(f\"Result 1: {result_a}\")\n\n        # Example 2: Demonstrate re-entrancy (calling duet.run within an async function)\n        # In most async libraries (e.g., asyncio, trio), this would raise a RuntimeError\n        # Duet explicitly allows it for easier refactoring of mixed sync/async code.\n        async def nested_task():\n            print(\"  Running nested_task synchronously via duet.run...\")\n            nested_future = executor.submit(long_running_sync_task, \"data_item_B\")\n            nested_result = await async_wrapper(nested_future)\n            print(f\"  Nested task result: {nested_result}\")\n            return \"Nested task completed\"\n\n        nested_call_result = duet.run(nested_task()) \n        print(f\"Result 2: {nested_call_result}\")\n\n    print(\"Duet example finished.\")\n\nif __name__ == \"__main__\":\n    duet.run(main())","lang":"python","description":"This quickstart demonstrates how to use Duet to run asynchronous code, wrap standard `concurrent.futures.Future` objects using `AwaitableFuture`, and showcases Duet's unique re-entrancy feature by calling `duet.run` within an already running async context."},"warnings":[{"fix":"Wrap your `concurrent.futures.Future` instance with `duet.AwaitableFuture(your_future)` before `await`ing it.","message":"When working with `concurrent.futures.Future` objects, they do not inherently support the `__await__` protocol. You must wrap them using `duet.AwaitableFuture` before you can `await` them directly within a Duet asynchronous function.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Understand that Duet allows nested `duet.run()` calls. If migrating from other async frameworks, adjust your expectations for loop re-entrancy or ensure you are not accidentally mixing event loops without proper bridging.","message":"Duet explicitly supports re-entrancy of its event loop, meaning you can call `duet.run()` from within an already running `duet.run()` context. This differs significantly from other popular async libraries like `asyncio` or `trio`, which would typically raise a `RuntimeError` in such a scenario. While this simplifies certain refactoring efforts, be aware of this unique behavior if you're accustomed to strict single-event-loop execution patterns.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"search_vec":"'0.2.9':16 'activ':80 'allow':37 'async':2,11,93 'async/await':38 'asynchron':63,75 'base':10 'bug':88 'cadenc':86 'call':57 'codebas':73 'concurr':26,94,98 'concurrent.futures.future':33 'context':64 'coroutin':39 'distinct':46 'duet':1,4,49 'duet.run':59 'entranc':54 'event':100 'event-loop':99 'featur':47 'fix':89 'futur':9,44,95 'future-bas':8 'improv':92 'increment':69 'inspir':19 'interact':41 'interfac':34 'librari':3,12,23,78 'loop':101 'maintain':81 'minor':91 'multipl':56 'one':76 'parallel':36 'permit':55 'primarili':28 'python':14 're':53 're-entr':52 'refactor':70 'releas':85 'reli':29 'simpl':7 'simplifi':67 'singl':62 'standard':32 'steadi':84 'structur':25,97 'structured-concurr':96 'synchron':72 'take':18 'trio':22 'version':15 'within':60","created_at":"2026-04-16T13:47:46.692962+00:00","updated_at":"2026-04-16T13:47:46.692962+00:00","problems":[{"fix":"Import `AwaitableFuture` from `duet` and wrap the future: `await duet.AwaitableFuture(your_future)`.","cause":"Attempting to `await` a `concurrent.futures.Future` object directly without wrapping it in `duet.AwaitableFuture`.","error":"TypeError: object Future can't be awaited"},{"fix":"Ensure you have imported the necessary components, e.g., `from duet import run` or `from duet import AwaitableFuture`.","cause":"The `run` function, or other Duet symbols, were used without being properly imported from the `duet` library.","error":"NameError: name 'run' is not defined"}],"ecosystem":"pypi","meta_description":null,"install_score":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":"0.2.9","cli_name":"","cli_version":null,"type":"library","homepage":null,"github":"http://github.com/google/duet","docs":null,"changelog":null,"pypi":"https://pypi.org/project/duet/","npm":null,"openapi_spec":null,"status_page":null,"smithery":null,"categories":["http-networking","workflow"],"base_url":null,"auth_type":null,"provenance":{"verified_status":"passing","verified_at":"2026-06-28","last_verified":"2026-06-28","next_check":"2026-07-28","install_tag":null}}