Skip to content

Introduction to Click

Note

If you know what Click is, you can skip this page.

rich-click is a drop-in replacement for Click, a Python CLI framework. This means that if you know Click, you already know rich-click. The docs to Click are the appropriate place to

Click 101

Commands

Click utilizes function decorators as its primary interface for composing a CLI.

For example, the @click.command decorator creates a Command object that calls the function:

# docs/code_snippets/introduction_to_click/hello.py
import click

@click.command()
def hello():
    """Prints 'hello, world!' into the terminal."""
    print("Hello, world!")

if __name__ == "__main__":
    hello()

You can run the file like normal, or you can run --help to render the function's docstring:

python hello.py

python hello.py --help

Arguments and Options

Arguments and options are also added with decorators. The difference between arguments and options is:

  • Arguments are required, and options are not (unless you specify required=True).
  • Arguments are positional, and options must be prefixed with one or two dashes.

The below code shows some of the features available with options and arguments:

# docs/code_snippets/introduction_to_click/hello_v2.py
import click

@click.command()
@click.argument("name")
@click.option("--times", "-t",
              default=1,
              type=click.INT,
              show_default=True,
              help="Number of times to print the greeting.")
@click.option("--say-goodbye",
              is_flag=True,
              default=False,
              help="After saying hello, say goodbye.")
def hello(name, times, say_goodbye):
    """Prints 'hello, [name]!' into the terminal N times."""
    for t in range(times):
        print(f"Hello, {name}!")
    if say_goodbye:
        print("Goodbye!")

if __name__ == "__main__":
    hello()

python hello_v2.py --say-goodbye --times 3 Edward

python hello_v2.py --help

Click is able to parse the new arguments and options, e.g. it knows that --times [number] maps to the function argument times. Additionally, Click also knows to render these new arguments in the help text.

Groups

Last but not least, Click allows for command groups and sub-commands, which allows you to nest commands inside other commands.

# docs/code_snippets/introduction_to_click/hello_v3.py
import click

@click.group("greetings")
def greetings_cli():
    """CLI for greetings."""

@greetings_cli.command("english")
@click.argument("name")
def english(name):
    """Greet in English"""
    print(f"Hello, {name}!")

@greetings_cli.command("french")
@click.argument("name")
def french(name):
    """Greet in French"""
    print(f"Bonjour, {name}!")

if __name__ == "__main__":
    greetings_cli()

Running python hello.py --help gives you the help text for the group and lists the subcommands:

python hello_v3.py --help

And you can run any of the subcommands like so:

python hello_v3.py french Jennifer

python hello_v3.py french --help

Next Steps

Info

There is a lot more to Click than what is covered here. Read the official Click docs for more information.

So, what does any of this have to do with rich-click? Simply put: rich-click is a drop-in replacement for Click. Let's take the second CLI example above with the --times option and add rich-click by replacing this:

import click

With this:

import rich_click as click

That's the only change needed to use rich-click! And now we get the following beautiful help text:

python hello_rich.py --help

Other CLI libraries

Click has been around for over a decade and is the most popular third-party CLI tool in Python. It's popularity is for a good reason: you can do basically anything in Click. Click is very well abstracted, and as a result, you will likely never feel like you are brushing up against the limitations of what Click is capable of.

There are other CLI libraries available. Of particular note is Typer, which is itself built on top of Click. Typer is also able to format help messages with Rich, functionality that was adapted from rich-click - as a result, the output looks remarkably similar! However, the two libraries have since drifted apart, so note that not all rich-click functionality is available within Typer.

Why Click?

If you're interested in why people choose to use Click, check out the Why Click? docs. These are good, but be aware that they were written a really long time ago. The landscape has changed quite a bit since that page was first written.