Composable Click Utilities
Click-compose is a Python library that provides composable utilities for enhancing Click callback functions, enabling the construction of flexible and modular command-line interface (CLI) applications. It extends the core functionality of the Click framework by offering tools to easily chain and combine command logic. The library is actively maintained, with its current version being 2025.10.27.3, and follows a frequent release cadence.
Common errors
-
TypeError: 'Command' object is not callable
cause Attempting to call a Click command directly that has been modified by a 'click-compose' decorator in a way that changes its callable interface without proper invocation via Click's `Context.invoke` or `CliRunner`.fixEnsure that `click` commands modified by `click-compose` are always invoked correctly within the Click ecosystem, typically through a parent `click.group` or `cli()` entry point, not as standalone Python functions. -
ModuleNotFoundError: No module named 'click_compose'
cause The 'click-compose' package is not installed in the current Python environment.fixRun `pip install click-compose` to install the library.
Warnings
- breaking Major version updates of the underlying 'click' library may introduce incompatibilities that require 'click-compose' to release a new version or for users to adjust their code.
- gotcha Incorrect order of decorators (e.g., Click's @command before @callback_group or @composed_option) can lead to unexpected behavior or errors, as Click's decorators often wrap the function directly.
Install
-
pip install click-compose
Imports
- callback_group
from click_compose import callback_group
- composed_option
from click_compose import composed_option
Quickstart
import click
from click_compose import callback_group, composed_option
@callback_group()
@click.command()
@click.option('--name', default='World', help='The name to greet.')
def cli(name):
"""A simple CLI greeting utility."""
click.echo(f'Hello, {name}!')
@cli.command()
@composed_option('--caps', is_flag=True, help='Say hello in uppercase.')
def shout(caps, name):
"""Greets in an excited manner."""
message = f'HEY {name.upper()}!' if caps else f'Hey {name}!'
click.echo(message)
if __name__ == '__main__':
cli()