AnyIO
raw JSON → 4.13.0 verified Tue May 12 auth: no python install: verified quickstart: verified
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).
pip install anyio Common errors
error ModuleNotFoundError: No module named 'anyio' ↓
cause The 'anyio' package is not installed in the Python environment.
fix
Install the 'anyio' package using pip: 'pip install anyio'.
error ImportError: cannot import name 'start_blocking_portal' from 'anyio' ↓
cause The 'start_blocking_portal' function is not available in the installed version of 'anyio'.
fix
Upgrade 'anyio' to the latest version using pip: 'pip install --upgrade anyio'.
error AttributeError: module 'anyio' has no attribute 'start_blocking_portal' ↓
cause The 'start_blocking_portal' function is not present in the installed version of 'anyio'.
fix
Ensure you have the latest version of 'anyio' installed by running: 'pip install --upgrade anyio'.
error ModuleNotFoundError: No module named 'anyio._backends' ↓
cause The 'anyio._backends' module is missing, possibly due to packaging issues.
fix
Ensure all necessary modules are included during packaging, especially when using tools like PyInstaller.
error RuntimeError: An attempt was made to start a new application while another is still running ↓
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.
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(). Warnings
breaking 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. ↓
fix Use 'except* ValueError as eg:' on Python 3.11+, or install the 'exceptiongroup' package and import ExceptionGroup from it on Python 3.10.
breaking TaskGroup.spawn() was removed in AnyIO 4. Calling it raises AttributeError. ↓
fix Replace 'await tg.spawn(fn, arg)' with the synchronous 'tg.start_soon(fn, arg)' (no await).
breaking 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. ↓
fix Use: from anyio.from_thread import start_blocking_portal
with start_blocking_portal() as portal: portal.call(fn)
deprecated The 'item_type' keyword argument to create_memory_object_stream() is deprecated and will be removed in a future major version. ↓
fix Use the generic syntax: create_memory_object_stream[MyType](max_buffer_size=N)
deprecated The 'cancellable' parameter of to_thread.run_sync() is a deprecated alias for 'abandon_on_cancel'. Passing it emits a DeprecationWarning. ↓
fix Replace cancellable=True with abandon_on_cancel=True.
gotcha 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). ↓
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.
gotcha 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. ↓
fix Spawn all concurrent work through anyio.create_task_group().start_soon() and avoid bare asyncio.create_task() inside AnyIO-managed code.
Install
pip install anyio[trio] pip install anyio[trio] pytest-anyio Install compatibility verified last tested: 2026-05-12
runtime variant status import time mem disk
3.10-alpine default 0.17s 6.4MB 20.0M
3.10-alpine trio 0.17s 6.4MB 24.8M
3.10-alpine trio 0.17s 6.4MB 37.1M
3.10-slim default 0.11s 6.4MB 21M
3.10-slim trio 0.11s 6.4MB 25M
3.10-slim trio 0.12s 6.4MB 38M
3.11-alpine default 0.28s 7.6MB 22.0M
3.11-alpine trio 0.28s 7.6MB 28.0M
3.11-alpine trio 0.28s 7.6MB 41.8M
3.11-slim default 0.23s 7.6MB 22M
3.11-slim trio 0.24s 7.6MB 28M
3.11-slim trio 0.23s 7.6MB 42M
3.12-alpine default 0.47s 10.1MB 13.8M
3.12-alpine trio 0.49s 10.1MB 19.5M
3.12-alpine trio 0.50s 10.1MB 33.0M
3.12-slim default 0.44s 10.1MB 14M
3.12-slim trio 0.47s 10.1MB 20M
3.12-slim trio 0.46s 10.1MB 33M
3.13-alpine default 0.20s 6.1MB 13.1M
3.13-alpine trio 0.20s 6.1MB 18.8M
3.13-alpine trio 0.20s 6.1MB 32.3M
3.13-slim default 0.20s 6.1MB 14M
3.13-slim trio 0.20s 6.1MB 19M
3.13-slim trio 0.20s 6.1MB 33M
3.9-alpine default 0.15s 6.3MB 19.4M
3.9-alpine trio 0.15s 6.4MB 24.2M
3.9-alpine trio 0.16s 6.4MB 36.3M
3.9-slim default 0.14s 6.3MB 20M
3.9-slim trio 0.13s 6.4MB 25M
3.9-slim trio 0.14s 6.4MB 37M
Imports
- run wrong
asyncio.run(main)correctimport anyio anyio.run(main) - create_task_group wrong
await tg.spawn(fn)correctfrom anyio import create_task_group async with create_task_group() as tg: tg.start_soon(fn) - create_memory_object_stream wrong
create_memory_object_stream(10, item_type=int)correctfrom anyio import create_memory_object_stream send, recv = create_memory_object_stream[int](max_buffer_size=10) - start_blocking_portal wrong
from anyio import start_blocking_portalcorrectfrom anyio.from_thread import start_blocking_portal with start_blocking_portal() as portal: portal.call(async_fn) - to_thread.run_sync wrong
await to_thread.run_sync(blocking_fn, cancellable=True)correctfrom anyio import to_thread await to_thread.run_sync(blocking_fn, abandon_on_cancel=True) - CancelScope
from anyio import CancelScope with CancelScope(deadline=...) as scope: ... - Path
from anyio import Path path = Path('/tmp/file') content = await path.read_text() - get_cancelled_exc_class wrong
except asyncio.CancelledError:correctfrom anyio import get_cancelled_exc_class try: await something() except get_cancelled_exc_class(): raise
Quickstart verified last tested: 2026-04-23
import anyio
async def fetch(name: str, delay: float) -> None:
print(f'{name}: starting')
await anyio.sleep(delay)
print(f'{name}: done after {delay}s')
async def main() -> None:
# Task group: all tasks run concurrently; exceptions surface as ExceptionGroup
async with anyio.create_task_group() as tg:
tg.start_soon(fetch, 'task-A', 1.0)
tg.start_soon(fetch, 'task-B', 0.5)
# Timeout via CancelScope
with anyio.move_on_after(2.0) as scope:
await anyio.sleep(5)
if scope.cancelled_caught:
print('timed out (moved on)')
# Run a blocking call in a thread
import time
result = await anyio.to_thread.run_sync(time.strftime, '%X')
print('wall-clock time from thread:', result)
if __name__ == '__main__':
# Default backend is asyncio; swap to 'trio' with no code changes
anyio.run(main, backend='asyncio')