click-compose

Composable Click callback utilities for building flexible CLI applications.

Installation

click-compose supports Python 3.11+.

$ pip install click-compose

Or with uv:

$ uv add click-compose

Usage

click-compose provides utilities for composing Click callbacks.

multi_callback

multi_callback creates a Click-compatible callback that applies multiple callbacks in sequence. This is useful when you want to apply multiple transformations or validators to a single value.

"""Example of using multi_callback."""

import click

from click_compose import multi_callback


def validator1(
    _ctx: click.Context, _param: click.Parameter, value: int
) -> int:
    """First validator."""
    return value


def validator2(
    _ctx: click.Context, _param: click.Parameter, value: int
) -> int:
    """Second validator."""
    return value


def transformer(
    _ctx: click.Context, _param: click.Parameter, value: int
) -> int:
    """Transform the value."""
    return value


@click.command()
@click.option(
    "--value",
    type=int,
    callback=multi_callback(callbacks=[validator1, validator2, transformer]),
)
def cmd(value: int) -> None:
    """Example command using multi_callback."""
    click.echo(message=value)


if __name__ == "__main__":
    cmd([])

The value is passed through each callback in order, with the output of one callback becoming the input to the next.

sequence_validator

sequence_validator wraps a single-value validator to apply it to a sequence of values. This is particularly useful with Click’s multiple=True option parameter.

"""Example of using sequence_validator."""

import click

from click_compose import sequence_validator


def validate_single_value(
    _ctx: click.Context | None, _param: click.Parameter | None, value: int
) -> int:
    """Validate a single value."""
    return value


@click.command()
@click.option(
    "--values",
    multiple=True,
    type=int,
    callback=sequence_validator(validator=validate_single_value),
)
def cmd(values: tuple[int, ...]) -> None:
    """Example command using sequence_validator."""
    click.echo(message=values)

Each element in the sequence is validated individually, and validation errors are raised for the specific element that fails.

deduplicate

deduplicate is a Click callback that removes duplicate values from a sequence while preserving the original order. This is particularly useful with Click’s multiple=True option parameter when you want to ensure unique values.

"""Example of using ``deduplicate``."""

import click

from click_compose import deduplicate


@click.command()
@click.option(
    "--tags",
    multiple=True,
    type=str,
    callback=deduplicate,
)
def cmd(tags: tuple[str, ...]) -> None:
    """Example command using ``deduplicate``."""
    click.echo(message=f"Unique tags: {', '.join(tags)}")


if __name__ == "__main__":
    cmd([])

The callback preserves the first occurrence of each value and removes subsequent duplicates. For example, if a user provides --tags foo --tags bar --tags foo, the result will be ('foo', 'bar').

API Reference

Composable Click callback utilities for building flexible CLI applications.

click_compose.sequence_validator(*, validator: Callable[[Context | None, Parameter | None, T], U]) Callable[[Context | None, Parameter | None, Sequence[T] | None], Sequence[U] | None]

Wrap a single-value validator to apply it to a sequence of values.

This function takes a Click callback that validates a single value and returns a new callback that applies the same validation to each element in a sequence. The validator can transform the type of each element.

Parameters:

validator – A Click callback that validates a single value.

Returns:

A Click callback that validates a sequence of values.

click_compose.deduplicate(ctx: Context | None, param: Parameter | None, sequence: Sequence[T] | None) Sequence[T] | None

Return the sequence with duplicates removed while preserving order.

click_compose.multi_callback(*, callbacks: Sequence[Callable[[...], T]]) Callable[[Context | None, Parameter | None, T], T]

Create a Click-compatible callback that applies multiple callbacks in sequence.

This function takes a sequence of Click callbacks and returns a new callback that applies each callback in order, threading the value through each one. Each callback can transform the type, allowing for flexible pipelines of transformations and validations.

Parameters:

callbacks – A sequence of Click callbacks to apply in order.

Returns:

A Click callback that applies all the given callbacks in sequence.

Reference