Format click help output nicely with rich
—
Utility functions for patching existing Click applications and various helper functions for working with Rich-Click components. These utilities enable integration with existing Click codebases and provide helper functionality for Rich-Click development.
Functions for monkey-patching existing Click applications to use Rich-Click formatting without code changes.
def patch(rich_config: Optional[RichHelpConfiguration] = None) -> None:
"""
Patch Click internals to use rich-click types.
This function monkey-patches Click's core classes and decorators
to use Rich-Click equivalents, enabling rich formatting for
existing Click applications without code modifications.
Parameters:
- rich_config (RichHelpConfiguration, optional): Configuration to apply globally
Effects:
- click.command -> rich_command
- click.group -> rich_group
- click.Command -> _PatchedRichCommand
- click.Group -> _PatchedRichGroup
- click.CommandCollection -> _PatchedRichCommandCollection
- click.MultiCommand -> _PatchedRichMultiCommand (Click < 9.0)
"""Usage example:
import click
import rich_click
# Existing Click application
@click.command()
@click.option('--name', help='Your name')
def hello(name):
"""Say hello."""
click.echo(f'Hello, {name}!')
# Patch Click to use Rich-Click formatting
rich_click.patch()
# Now the existing Click app will use rich formatting
if __name__ == '__main__':
hello()Internal classes used by the patching system to provide Rich-Click functionality to existing Click applications.
class _PatchedRichCommand(RichCommand):
"""
Patched Rich command class.
Internal class used when patching Click.Command to provide
rich formatting capabilities.
"""
class _PatchedRichGroup(RichGroup, _PatchedRichCommand):
"""
Patched Rich group class.
Internal class used when patching Click.Group to provide
rich formatting capabilities for command groups.
"""
class _PatchedRichCommandCollection(RichCommandCollection, _PatchedRichCommand):
"""
Patched Rich command collection class.
Internal class used when patching Click.CommandCollection.
"""
class _PatchedRichMultiCommand(RichMultiCommand, _PatchedRichCommand):
"""
Patched Rich multi-command class (deprecated).
Internal class used when patching Click.MultiCommand in Click < 9.0.
"""Internal decorator functions used by the patching system.
def rich_command(*args, **kwargs):
"""
Patched command decorator.
Internal function that replaces click.command when patching
is enabled. Uses _PatchedRichCommand by default.
Parameters:
- *args: Positional arguments for command
- **kwargs: Keyword arguments for command
Returns:
Union[Command, Callable]: Command or decorator function
"""
def rich_group(*args, **kwargs):
"""
Patched group decorator.
Internal function that replaces click.group when patching
is enabled. Uses _PatchedRichGroup by default.
Parameters:
- *args: Positional arguments for group
- **kwargs: Keyword arguments for group
Returns:
Union[Group, Callable]: Group or decorator function
"""Helper functions for working with Rich-Click components and configuration.
def truthy(o: Any) -> Optional[bool]:
"""
Check if string or other object is truthy.
Converts string representations of boolean values to boolean,
handling common string formats used in environment variables
and configuration.
Parameters:
- o (Any): Object to check for truthiness
Returns:
Optional[bool]: Boolean value or None if indeterminate
Examples:
- truthy("y") -> True
- truthy("yes") -> True
- truthy("true") -> True
- truthy("1") -> True
- truthy("n") -> False
- truthy("no") -> False
- truthy("false") -> False
- truthy("0") -> False
- truthy("maybe") -> None
- truthy(None) -> None
- truthy(42) -> True
- truthy(0) -> False
"""
def method_is_from_subclass_of(cls: Type[object], base_cls: Type[object], method_name: str) -> bool:
"""
Check if a class's method comes from a subclass of some base class.
Used to determine whether a patched RichCommand's help text methods
are compatible with rich-click or might cause issues.
Parameters:
- cls (Type[object]): Class to check
- base_cls (Type[object]): Base class to check against
- method_name (str): Name of method to check
Returns:
bool: True if method comes from subclass of base_cls
"""Usage examples:
import rich_click as click
# Using truthy for environment variable parsing
import os
debug_mode = click.truthy(os.getenv('DEBUG', 'false'))
verbose = click.truthy(os.getenv('VERBOSE'))
@click.command()
def my_command():
"""Command that uses environment variables."""
if debug_mode:
click.echo("Debug mode enabled")
if verbose:
click.echo("Verbose output enabled")
# Using method_is_from_subclass_of for compatibility checking
from rich_click.utils import method_is_from_subclass_of
class MyCommand(click.RichCommand):
def format_help(self, ctx, formatter):
# Custom help formatting
return super().format_help(ctx, formatter)
# Check if format_help method is compatible
is_compatible = method_is_from_subclass_of(
MyCommand,
click.RichCommand,
'format_help'
)TypedDict definitions for configuration structures used in Rich-Click.
class CommandGroupDict(TypedDict):
"""
Specification for command groups.
Used to define groups of commands for organized help display.
Attributes:
- name (str, optional): Display name for the group
- commands (List[str]): List of command names in the group
- table_styles (Dict[str, Any], optional): Styling for the group table
- panel_styles (Dict[str, Any], optional): Styling for the group panel
- deduplicate (bool, optional): Whether to deduplicate commands
"""
class OptionGroupDict(TypedDict):
"""
Specification for option groups.
Used to define groups of options for organized help display.
Attributes:
- name (str, optional): Display name for the group
- options (List[str], optional): List of option names in the group
- table_styles (Dict[str, Any], optional): Styling for the group table
- panel_styles (Dict[str, Any], optional): Styling for the group panel
- deduplicate (bool, optional): Whether to deduplicate options
"""Usage examples for type definitions:
import rich_click as click
# Define command groups
command_groups = [
click.CommandGroupDict(
name="Database Commands",
commands=["init-db", "migrate", "seed"],
panel_styles={"border_style": "blue"}
),
click.CommandGroupDict(
name="Server Commands",
commands=["run", "debug", "test"],
panel_styles={"border_style": "green"}
)
]
# Define option groups
option_groups = [
click.OptionGroupDict(
name="Configuration",
options=["--config", "--env"],
table_styles={"show_lines": True}
),
click.OptionGroupDict(
name="Output Control",
options=["--verbose", "--quiet", "--format"],
panel_styles={"title_justify": "center"}
)
]
# Apply to configuration
config = click.RichHelpConfiguration(
command_groups={"mycli": command_groups},
option_groups={"mycli": option_groups}
)
@click.group()
@click.rich_config(config)
def mycli():
"""My CLI application with grouped commands and options."""
passDeprecated patch function maintained for backward compatibility.
def patch(*args, **kwargs):
"""
Deprecated patch function from rich_click.cli.
This function has moved to rich_click.patch.patch().
Using this import location is deprecated.
Parameters:
- *args: Arguments passed to rich_click.patch.patch()
- **kwargs: Keyword arguments passed to rich_click.patch.patch()
Raises:
DeprecationWarning: When used, indicating the new import location
"""Examples of integrating Rich-Click utilities with existing applications:
import click
import rich_click
from rich_click.utils import truthy
# Configuration from environment
def load_config_from_env():
"""Load configuration from environment variables."""
return {
'show_arguments': truthy(os.getenv('RICH_SHOW_ARGS', 'false')),
'use_markdown': truthy(os.getenv('RICH_USE_MARKDOWN', 'false')),
'style_option': os.getenv('RICH_OPTION_STYLE', 'bold cyan')
}
# Conditional patching
def maybe_patch_click():
"""Conditionally patch Click based on environment."""
if truthy(os.getenv('USE_RICH_CLICK', 'true')):
config = rich_click.RichHelpConfiguration(**load_config_from_env())
rich_click.patch(rich_config=config)
# Use in existing Click application
maybe_patch_click()
@click.command()
@click.option('--debug', is_flag=True, help='Enable debug mode')
def my_app(debug):
"""My existing Click application."""
if debug:
click.echo("Debug mode enabled")Install with Tessl CLI
npx tessl i tessl/pypi-rich-click