{"id":3888,"library":"asyncclick","title":"Async Click","description":"Asyncclick is a fork of Click that works seamlessly with Trio or asyncio, enabling the use of asynchronous command and subcommand handlers for building composable command line interfaces. It aims to provide the familiar Click API with added async capabilities. The current version is 8.3.0.7, released on October 11, 2025, and generally follows the upstream Click project's release cadence.","status":"active","version":"8.3.0.7","language":"en","source_language":"en","source_url":"https://github.com/python-trio/asyncclick/","tags":["cli","async","asyncio","trio","command-line","click"],"install":[{"cmd":"pip install asyncclick","lang":"bash","label":"Install stable version"}],"dependencies":[{"reason":"asyncclick is a fork of Click and shares much of its underlying structure. While you import from `asyncclick`, `click` is an implicit dependency.","package":"click"},{"reason":"Provides the async compatibility layer, allowing asyncclick to work with both asyncio and Trio event loops. Explicitly used in examples to run the CLI asynchronously.","package":"anyio"},{"reason":"Requires Python 3.11 or newer for the latest version.","package":"python","optional":false}],"imports":[{"note":"Asyncclick replaces the standard Click imports for async functionality. Do not mix imports from `click` and `asyncclick` in the same program.","wrong":"from click import command","symbol":"command","correct":"from asyncclick import command"},{"note":"Asyncclick replaces the standard Click imports for async functionality. Do not mix imports from `click` and `asyncclick` in the same program.","wrong":"from click import group","symbol":"group","correct":"from asyncclick import group"},{"note":"Asyncclick replaces the standard Click imports for async functionality. Do not mix imports from `click` and `asyncclick` in the same program.","wrong":"from click import option","symbol":"option","correct":"from asyncclick import option"},{"note":"Asyncclick replaces the standard Click imports for async functionality. Do not mix imports from `click` and `asyncclick` in the same program.","wrong":"from click import echo","symbol":"echo","correct":"from asyncclick import echo"},{"note":"When migrating from Click, replace `import click` with `import asyncclick as click` to seamlessly use async-enabled handlers. Mixing direct imports is not supported.","wrong":"import click","symbol":"click (alias)","correct":"import asyncclick as click"}],"quickstart":{"code":"import asyncclick as click\nimport anyio\n\n@click.command()\n@click.option(\"--count\", default=1, help=\"Number of greetings.\")\n@click.option(\"--name\", prompt=\"Your name\", help=\"The person to greet.\")\nasync def hello(count, name):\n    \"\"\"Simple program that greets NAME for a total of COUNT times.\"\"\"\n    for _ in range(count):\n        click.echo(f\"Hello, {name}!\")\n        await anyio.sleep(0.1) # Simulate async I/O\n\nif __name__ == '__main__':\n    # asyncclick automatically starts an anyio event loop\n    # and runs your code asynchronously.\n    hello()","lang":"python","description":"This quickstart demonstrates a basic asynchronous command using `asyncclick`. It defines a command with options and arguments, and includes an `await` call to simulate an asynchronous operation, showcasing `asyncclick`'s core functionality."},"warnings":[{"fix":"Ensure all calls to `asyncclick.prompt` are prefixed with `await`. Consider the `blocking` parameter if dealing with interrupt handling.","message":"`asyncclick.prompt` is now asynchronous and must be awaited. It also introduces a `blocking` parameter.","severity":"breaking","affected_versions":"8.3.0 and newer"},{"fix":"Replace `Context.exit` calls with `await Context.aexit` to correctly handle asynchronous teardown callbacks and context managers.","message":"`Context.exit` has been renamed to `Context.aexit` and is now an asynchronous method.","severity":"breaking","affected_versions":"8.3.0 and newer"},{"fix":"Replace `import click` with `import asyncclick as click` and ensure all decorators and functions (`command`, `option`, `group`, `echo`, etc.) are imported from `asyncclick`.","message":"Do not mix direct imports from the synchronous `click` library and `asyncclick` in the same program.","severity":"gotcha","affected_versions":"All versions"},{"fix":"For CPU-bound tasks, use `anyio.to_thread.run_sync()` or `asyncio.to_thread()` (or `loop.run_in_executor` for older `asyncio`) to offload work to a thread pool. For blocking I/O, use async-native libraries (e.g., `aiohttp` instead of `requests`).","message":"Performing blocking synchronous I/O or CPU-bound operations directly in `async` command handlers will block the event loop, negating the benefits of async programming.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Consult the Click 8.x changelog for specific deprecations. Prefer using `Command` and `Group` for base classes and `importlib.metadata.version` for version retrieval.","message":"Asyncclick inherits deprecations from upstream Click. For example, `BaseCommand` and `MultiCommand` are deprecated in favor of `Command` and `Group` respectively, and the `__version__` attribute is deprecated in favor of `importlib.metadata.version(\"click\")`.","severity":"deprecated","affected_versions":"8.3.0 and newer (inherited from Click 8.3.0)"}],"env_vars":null,"last_verified":"2026-04-11T00:00:00.000Z","next_check":"2026-07-10T00:00:00.000Z"}