{"id":261,"library":"anyio","title":"AnyIO","description":"AnyIO is a high-level asynchronous networking and concurrency library that runs on top of either asyncio or Trio, implementing Trio-like structured concurrency on both backends. Code written against AnyIO's API runs unmodified on either backend, allowing incremental adoption. Current stable version is 4.13.0, with an active monthly-ish release cadence under Alex Grönholm (agronholm).","status":"active","version":"4.13.0","language":"python","source_language":"en","source_url":"https://github.com/agronholm/anyio","tags":["async","concurrency","asyncio","trio","structured-concurrency","networking","threads","task-group"],"install":[{"cmd":"pip install anyio","lang":"bash","label":"asyncio backend (default)"},{"cmd":"pip install anyio[trio]","lang":"bash","label":"with Trio backend support"},{"cmd":"pip install anyio[trio] pytest-anyio","lang":"bash","label":"with Trio + built-in pytest plugin"}],"dependencies":[{"reason":"Required only for the Trio backend; install via anyio[trio] extra","package":"trio","optional":true},{"reason":"Used for IDNA 2008 hostname resolution on asyncio; installed automatically","package":"idna","optional":true},{"reason":"Backport of PEP 654 ExceptionGroup for Python < 3.11; required if catching exception groups on older Pythons","package":"exceptiongroup","optional":true}],"imports":[{"note":"Use anyio.run() to stay backend-agnostic; pass backend='trio' or backend='asyncio' explicitly when needed","wrong":"asyncio.run(main)","symbol":"run","correct":"import anyio\nanyio.run(main)"},{"note":"TaskGroup.spawn() was removed in AnyIO 4; use the synchronous tg.start_soon() instead","wrong":"await tg.spawn(fn)","symbol":"create_task_group","correct":"from anyio import create_task_group\nasync with create_task_group() as tg:\n    tg.start_soon(fn)"},{"note":"The item_type keyword argument is deprecated; use the generic bracket syntax create_memory_object_stream[T]()","wrong":"create_memory_object_stream(10, item_type=int)","symbol":"create_memory_object_stream","correct":"from anyio import create_memory_object_stream\nsend, recv = create_memory_object_stream[int](max_buffer_size=10)"},{"note":"start_blocking_portal lives in anyio.from_thread, not the top-level anyio namespace; must be used as a context manager","wrong":"from anyio import start_blocking_portal","symbol":"start_blocking_portal","correct":"from anyio.from_thread import start_blocking_portal\nwith start_blocking_portal() as portal:\n    portal.call(async_fn)"},{"note":"The 'cancellable' parameter is a deprecated alias for 'abandon_on_cancel'; use abandon_on_cancel instead","wrong":"await to_thread.run_sync(blocking_fn, cancellable=True)","symbol":"to_thread.run_sync","correct":"from anyio import to_thread\nawait to_thread.run_sync(blocking_fn, abandon_on_cancel=True)"},{"note":"CancelScope is a plain synchronous context manager since AnyIO 3; do NOT use 'async with'","symbol":"CancelScope","correct":"from anyio import CancelScope\nwith CancelScope(deadline=...) as scope:\n    ..."},{"note":"anyio.Path is NOT a drop-in replacement for pathlib.Path; it cannot be passed to APIs expecting pathlib.Path","symbol":"Path","correct":"from anyio import Path\npath = Path('/tmp/file')\ncontent = await path.read_text()"},{"note":"The cancellation exception differs between backends; use get_cancelled_exc_class() to catch it portably","wrong":"except asyncio.CancelledError:","symbol":"get_cancelled_exc_class","correct":"from anyio import get_cancelled_exc_class\ntry:\n    await something()\nexcept get_cancelled_exc_class():\n    raise"}],"quickstart":{"code":"import anyio\n\nasync def fetch(name: str, delay: float) -> None:\n    print(f'{name}: starting')\n    await anyio.sleep(delay)\n    print(f'{name}: done after {delay}s')\n\nasync def main() -> None:\n    # Task group: all tasks run concurrently; exceptions surface as ExceptionGroup\n    async with anyio.create_task_group() as tg:\n        tg.start_soon(fetch, 'task-A', 1.0)\n        tg.start_soon(fetch, 'task-B', 0.5)\n\n    # Timeout via CancelScope\n    with anyio.move_on_after(2.0) as scope:\n        await anyio.sleep(5)\n    if scope.cancelled_caught:\n        print('timed out (moved on)')\n\n    # Run a blocking call in a thread\n    import time\n    result = await anyio.to_thread.run_sync(time.strftime, '%X')\n    print('wall-clock time from thread:', result)\n\nif __name__ == '__main__':\n    # Default backend is asyncio; swap to 'trio' with no code changes\n    anyio.run(main, backend='asyncio')","lang":"python","description":"Demonstrates concurrent task groups, move_on_after timeout scopes, and offloading blocking calls to a worker thread — all backend-agnostic."},"warnings":[{"fix":"Use 'except* ValueError as eg:' on Python 3.11+, or install the 'exceptiongroup' package and import ExceptionGroup from it on Python 3.10.","message":"In AnyIO 4, task groups always raise ExceptionGroup (PEP 654) when any child task raises. The old anyio.ExceptionGroup class was removed. Code catching exceptions from task groups must use 'except*' syntax (Python 3.11+) or the 'exceptiongroup' backport on older Pythons.","severity":"breaking","affected_versions":"<4.0"},{"fix":"Replace 'await tg.spawn(fn, arg)' with the synchronous 'tg.start_soon(fn, arg)' (no await).","message":"TaskGroup.spawn() was removed in AnyIO 4. Calling it raises AttributeError.","severity":"breaking","affected_versions":"<4.0"},{"fix":"Use: from anyio.from_thread import start_blocking_portal\nwith start_blocking_portal() as portal: portal.call(fn)","message":"start_blocking_portal() was moved to anyio.from_thread and must be used as a synchronous context manager. Importing it from the top-level anyio namespace raises ImportError.","severity":"breaking","affected_versions":"<3.0"},{"fix":"Use the generic syntax: create_memory_object_stream[MyType](max_buffer_size=N)","message":"The 'item_type' keyword argument to create_memory_object_stream() is deprecated and will be removed in a future major version.","severity":"deprecated","affected_versions":">=4.0"},{"fix":"Replace cancellable=True with abandon_on_cancel=True.","message":"The 'cancellable' parameter of to_thread.run_sync() is a deprecated alias for 'abandon_on_cancel'. Passing it emits a DeprecationWarning.","severity":"deprecated","affected_versions":">=4.x"},{"fix":"Pass str(anyio_path) to third-party APIs expecting pathlib.Path, or open the file with await anyio_path.open() and hand the file object over.","message":"anyio.Path cannot be substituted for pathlib.Path. APIs expecting a pathlib.Path will reject an anyio.Path instance; convert with str(path) or pass the underlying pathlib.Path via path._path (private, unstable).","severity":"gotcha","affected_versions":"all"},{"fix":"Spawn all concurrent work through anyio.create_task_group().start_soon() and avoid bare asyncio.create_task() inside AnyIO-managed code.","message":"Mixing native asyncio tasks (asyncio.create_task) with AnyIO cancel scopes can cause tasks spawned outside AnyIO to escape cancellation, and await inside a finally block can receive multiple CancelledError instances under scoped cancellation.","severity":"gotcha","affected_versions":"all"}],"env_vars":null,"last_verified":"2026-05-12T12:28:12.125Z","next_check":"2026-06-26T00:00:00.000Z","problems":[{"fix":"Install the 'anyio' package using pip: 'pip install anyio'.","cause":"The 'anyio' package is not installed in the Python environment.","error":"ModuleNotFoundError: No module named 'anyio'"},{"fix":"Upgrade 'anyio' to the latest version using pip: 'pip install --upgrade anyio'.","cause":"The 'start_blocking_portal' function is not available in the installed version of 'anyio'.","error":"ImportError: cannot import name 'start_blocking_portal' from 'anyio'"},{"fix":"Ensure you have the latest version of 'anyio' installed by running: 'pip install --upgrade anyio'.","cause":"The 'start_blocking_portal' function is not present in the installed version of 'anyio'.","error":"AttributeError: module 'anyio' has no attribute 'start_blocking_portal'"},{"fix":"Ensure all necessary modules are included during packaging, especially when using tools like PyInstaller.","cause":"The 'anyio._backends' module is missing, possibly due to packaging issues.","error":"ModuleNotFoundError: No module named 'anyio._backends'"},{"fix":"If you are already inside an async context, use `anyio.create_task_group().start_soon()` or `anyio.to_thread.run_sync()` for blocking calls, instead of `anyio.run()`. If you need to run async code from a synchronous thread not managed by AnyIO, use `anyio.from_thread.run()` or `anyio.from_thread.start_blocking_portal()`.","cause":"This error occurs when trying to call `anyio.run()` (or `asyncio.run()`) from within a thread where an asynchronous event loop is already active. AnyIO's `run()` function is designed to start an event loop, not to be called from inside one.","error":"RuntimeError: An attempt was made to start a new application while another is still running"}],"ecosystem":"pypi","meta_description":null,"install_score":100,"install_tag":"verified","quickstart_score":80,"quickstart_tag":"verified","pypi_latest":null,"install_checks":{"last_tested":"2026-05-12","tag":"verified","tag_description":"installs cleanly on critical runtimes, fast import, recently tested","results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.17,"mem_mb":6.4,"disk_size":"20.0M"},{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"trio","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.17,"mem_mb":6.4,"disk_size":"24.8M"},{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"trio","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.17,"mem_mb":6.4,"disk_size":"37.1M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.11,"mem_mb":6.4,"disk_size":"21M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"trio","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.11,"mem_mb":6.4,"disk_size":"25M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"trio","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.12,"mem_mb":6.4,"disk_size":"38M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.28,"mem_mb":7.6,"disk_size":"22.0M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"trio","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.28,"mem_mb":7.6,"disk_size":"28.0M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"trio","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.28,"mem_mb":7.6,"disk_size":"41.8M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.23,"mem_mb":7.6,"disk_size":"22M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"trio","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.24,"mem_mb":7.6,"disk_size":"28M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"trio","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.23,"mem_mb":7.6,"disk_size":"42M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.47,"mem_mb":10.1,"disk_size":"13.8M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"trio","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.49,"mem_mb":10.1,"disk_size":"19.5M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"trio","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.5,"mem_mb":10.1,"disk_size":"33.0M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.44,"mem_mb":10.1,"disk_size":"14M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"trio","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.47,"mem_mb":10.1,"disk_size":"20M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"trio","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.46,"mem_mb":10.1,"disk_size":"33M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.2,"mem_mb":6.1,"disk_size":"13.1M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"trio","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.2,"mem_mb":6.1,"disk_size":"18.8M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"trio","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.2,"mem_mb":6.1,"disk_size":"32.3M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.2,"mem_mb":6.1,"disk_size":"14M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"trio","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.2,"mem_mb":6.1,"disk_size":"19M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"trio","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.2,"mem_mb":6.1,"disk_size":"33M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.15,"mem_mb":6.3,"disk_size":"19.4M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"trio","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.15,"mem_mb":6.4,"disk_size":"24.2M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"trio","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.16,"mem_mb":6.4,"disk_size":"36.3M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.14,"mem_mb":6.3,"disk_size":"20M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"trio","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.13,"mem_mb":6.4,"disk_size":"25M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"trio","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.14,"mem_mb":6.4,"disk_size":"37M"}]},"quickstart_checks":{"last_tested":"2026-04-23","tag":"verified","tag_description":"quickstart runs on critical runtimes, recently tested","results":[{"runtime":"python:3.10-alpine","exit_code":0},{"runtime":"python:3.10-slim","exit_code":0},{"runtime":"python:3.11-alpine","exit_code":0},{"runtime":"python:3.11-slim","exit_code":0},{"runtime":"python:3.12-alpine","exit_code":0},{"runtime":"python:3.12-slim","exit_code":0},{"runtime":"python:3.13-alpine","exit_code":0},{"runtime":"python:3.13-slim","exit_code":0},{"runtime":"python:3.9-alpine","exit_code":0},{"runtime":"python:3.9-slim","exit_code":0}]}}