Click

raw JSON →
8.3.1 verified Tue May 12 auth: no python install: verified quickstart: stale

Click ('Command Line Interface Creation Kit') is a Python package for creating composable, beautiful command-line interfaces with minimal boilerplate. It uses a decorator-based API to turn functions into CLI commands with automatic help page generation, argument/option parsing, type coercion, and shell completion. Current version is 8.3.1 (latest stable); the project follows a feature-release / fix-release cadence under the Pallets organization, with feature releases (e.g. 8.2.0, 8.3.0) potentially introducing deprecations or breaking changes and patch releases (e.g. 8.3.1) being safe upgrades.

pip install click
error ModuleNotFoundError: No module named 'click'
cause The 'click' library is not installed in the Python environment being used, or the Python interpreter running the script is not the one where 'click' is installed.
fix
Install the 'click' library using pip: pip install click. If using a virtual environment, ensure it is activated before installation.
error Error: Missing command.
cause A required subcommand was not provided when executing a Click group, or the group was invoked without any arguments and `invoke_without_command` is not set to `True`.
fix
Provide the expected subcommand as an argument (e.g., your_script.py subcommand), or add invoke_without_command=True to your @click.group() decorator if the group should run its callback even without a subcommand. Consult the help page with your_script.py --help to see available commands.
error TypeError: 'Group' object is not callable
cause A `click.Group` or `click.Command` object is being directly called like a regular Python function, instead of allowing Click's internal dispatch mechanism (via `main()` or `invoke()`) to handle its execution.
fix
Ensure that your top-level command or group is executed via if __name__ == '__main__': your_cli_function(). If you need to invoke a subcommand from within another command's callback, use ctx.invoke(subcommand_callback, ...) or group_object.invoke(ctx).
error Error: Missing argument '<name>'
cause A required argument for a Click command or option was not provided on the command line.
fix
Supply the missing argument when running the command (e.g., your_script.py <value_for_name>). Review the command's expected arguments and options using your_script.py --help.
breaking Python 3.7, 3.8, and 3.9 support was dropped in Click 8.2.0. Projects running on those versions must pin to click<8.2.
fix Upgrade Python to >=3.10 (required by current 8.3.x) or pin 'click<8.2' if stuck on older Python.
deprecated BaseCommand and MultiCommand are deprecated since 8.2.0. Subclassing or isinstance-checking either will emit DeprecationWarnings and will break in a future major release.
fix Replace BaseCommand subclasses with Command and MultiCommand subclasses/isinstance checks with Group.
deprecated click.__version__ is deprecated since 8.2.0. Accessing it emits a DeprecationWarning.
fix Use 'importlib.metadata.version("click")' for runtime version detection.
breaking click.get_terminal_size was removed in 8.1.0. Any code importing it from click will raise ImportError. Third-party packages that imported it (e.g. older spaCy) broke on upgrade.
fix Use 'shutil.get_terminal_size()' from the Python standard library instead.
gotcha CliRunner.invoke() catches ALL exceptions by default (catch_exceptions=True), silently swallowing bugs. Tests may pass with exit_code != 0 if result.exception is not inspected.
fix Pass catch_exceptions=False to CliRunner.invoke() during development, or always assert result.exception is None and result.exit_code == 0 in tests.
gotcha CliRunner is not thread-safe and mutates global interpreter state (sys.stdout, sys.stdin). Do not use it in threaded or async test suites without isolation.
fix Run CliRunner tests sequentially. Use runner.isolated_filesystem() for file-based tests to avoid cross-test contamination.
gotcha standalone_mode=True (the default) means Click calls sys.exit() after command execution, converting return values to exit codes. Calling a click command directly in application code without standalone_mode=False will terminate the process.
fix Invoke programmatically with standalone_mode=False: result = my_command.main(args=[], standalone_mode=False) to get the return value instead of a sys.exit().
gotcha Click applications display the usage and help message when invoked without a specific command or with invalid arguments. This is expected behavior but can be unexpected if the intention was to execute a command, and no default command is configured.
fix Ensure the script is invoked with the intended command and arguments. If the application should perform an action without an explicit command, configure a default command or handle argument parsing explicitly.
python os / libc status wheel install import disk
3.10 alpine (musl) - - 0.04s 18.5M
3.10 slim (glibc) - - 0.03s 19M
3.11 alpine (musl) - - 0.07s 20.5M
3.11 slim (glibc) - - 0.06s 21M
3.12 alpine (musl) - - 0.07s 12.3M
3.12 slim (glibc) - - 0.07s 13M
3.13 alpine (musl) - - 0.06s 12.0M
3.13 slim (glibc) - - 0.06s 12M
3.9 alpine (musl) - - 0.04s 18.0M
3.9 slim (glibc) - - 0.04s 18M

A minimal Click CLI with a group, a subcommand, options, and a test via CliRunner.

import click
from click.testing import CliRunner

@click.group()
@click.option('--verbose', is_flag=True, default=False, help='Enable verbose output.')
@click.pass_context
def cli(ctx, verbose):
    """My CLI tool."""
    ctx.ensure_object(dict)
    ctx.obj['verbose'] = verbose

@cli.command()
@click.option('--count', default=1, show_default=True, help='Number of greetings.')
@click.option('--name', prompt='Your name', help='Person to greet.')
@click.pass_context
def greet(ctx, count, name):
    """Greet NAME a number of times."""
    for _ in range(count):
        click.echo(f"Hello, {name}!")
    if ctx.obj.get('verbose'):
        click.echo(f"(verbose mode, greeted {count} time(s))")

if __name__ == '__main__':
    # Direct invocation
    cli()

# --- Testing ---
def test_greet():
    runner = CliRunner()
    result = runner.invoke(cli, ['greet', '--name', 'World', '--count', '2'])
    assert result.exit_code == 0, result.output
    assert result.output.count('Hello, World!') == 2

test_greet()
click.echo('Quickstart test passed.')