python-cli
Python CLI with Click
Structure Python CLIs using Click with composable subcommand groups.
Project Structure
.
├── pyproject.toml # console_script points to `your_package.cli:main`
└── your_package/
├── __init__.py
├── cli.py # root Click group; imports and registers subcommands
├── foo/
│ ├── __init__.py
│ └── commands.py # exposes a Click group named `cli`
└── bar/
├── __init__.py
└── commands.py # exposes a Click group named `cli`
Root CLI Entry Point
import click
from .foo.commands import cli as foo
from .bar.commands import cli as bar
CONTEXT_SETTINGS = {"help_option_names": ["-h", "--help"]}
@click.group(context_settings=CONTEXT_SETTINGS)
def cli() -> None:
"""Project command line interface."""
pass
@cli.command()
@click.option("--name", "-n", default="world", help="Who to greet.")
def hello(name: str) -> None:
"""Example subcommand."""
click.echo(f"Hello, {name}!")
def main() -> None:
cli()
# Register imported subcommand groups with explicit names
cli.add_command(foo, name="foo")
cli.add_command(bar, name="bar")
if __name__ == "__main__":
main()
Subcommand Module (foo/commands.py)
import click
@click.group()
def cli() -> None:
"""Foo subcommands."""
pass
@cli.command()
@click.argument("item")
def process(item: str) -> None:
"""Process a single item."""
click.echo(f"Processing: {item}")
pyproject.toml Entry Point
[project.scripts]
my-tool = "your_package.cli:main"
Key Patterns
- One group per module: Each subcommand directory exports a Click group named
cli - Explicit registration: Use
cli.add_command(group, name="name")in the root CLI - Context settings: Always set
help_option_names = ["-h", "--help"] - Console scripts: Wire up the entry point in
pyproject.tomlforuv pip install -e .
Bookkeeping
After modifying the CLI, update the adjacent README.md to reflect the current command surface.
More from brojonat/llmsrules
ibis-data
Use Ibis for database-agnostic data access in Python. Use when writing data queries, connecting to databases (DuckDB, PostgreSQL, SQLite), or building portable data pipelines that should work across backends.
13go-service
Build Go microservices with stdlib HTTP handlers, sqlc, urfave/cli, and slog. Use when creating or modifying a Go HTTP server, adding routes, middleware, database queries, or CLI commands.
13temporal-go
Build Temporal workflow applications in Go. Use when creating or modifying Temporal workflows, activities, workers, clients, signals, queries, updates, retry policies, saga patterns, or writing Temporal tests.
13parquet-analysis
Analyze parquet files using Python and Ibis. Use when the user wants to explore, transform, or analyze parquet data files, perform aggregations, joins, or export results. Works with local parquet files and provides database-agnostic data operations.
12ducklake
Work with DuckLake, an open lakehouse format built on DuckDB. Use when creating or querying DuckLake tables, managing snapshots, time travel, schema evolution, partitioning, or lakehouse maintenance operations.
12temporal-python
Build Temporal applications in Python using the temporalio SDK. Use when creating workflows, activities, workers, clients, signals, queries, updates, child workflows, timers, retry policies, saga/compensation patterns, testing, or any durable execution pattern in Python.
12