Click and Typer backends¶
cliffy can generate two kinds of code from the same manifest.
| Typer (default) | Click | |
|---|---|---|
| Enable with | nothing | use_click: true |
| Generated code uses | typer |
rich_click, or plain click when rich-click is not installed |
| Extra install | none | none. pip install "cliffy[rich]" adds rich-formatted help |
| Supported manifest features | all | all, with the differences listed below |
Use Typer unless you have a specific reason to generate Click code. Typer is the backend the rest of this documentation describes.
The Click backend¶
name: clicky
version: 0.1.0
help: The same manifest format, rendered with Click
use_click: true
commands:
hello|hi:
help: Say hello
params:
- name: str!
- --times: int = 1
run: |
for _ in range(times):
print(f"hello {name}")
resize:
help: Explicit params work like in Typer
params:
- name: image
type: str
required: true
help: File to resize
- name: --width
type: int
short: -w
default: 800
help: Target width
run: print(image, width)
tag:
help: Raw Click decorators
params:
- "@click.option('--loud', is_flag=True, help='Shout the tags')"
- "@click.argument('tags', nargs=-1)"
run: |
for tag in tags:
print(tag.upper() if loud else tag)
db.migrate:
help: Groups work the same way
run: $ echo "migrating"
tests:
- hello Ada --times 2: assert result.output == "hello Ada\nhello Ada\n"
- hi Ada: assert result.output == "hello Ada\n"
- resize cat.jpg -w 100: assert result.output == "cat.jpg 100\n"
- resize: assert result.exit_code == 2
- tag --loud a b: assert result.output == "A\nB\n"
- db migrate: assert result.exit_code == 0
$ cli run click.yaml -- hello Ada --times 2
hello Ada
hello Ada
$ cli run click.yaml -- resize cat.jpg -w 100
cat.jpg 100
$ cli run click.yaml -- tag --loud a b
A
B
$ cli run click.yaml db migrate
migrating
What works¶
- Commands, groups (
db.migrate) and aliases (hello|hi) - Shorthand and explicit params with the same meaning as for Typer: a name with
--is an option, anything else is a positional argument,!orrequired: truemakes it required, andshort,defaultandhelpare passed on types, commandconfig,global_params,callbacks,pre_run,post_runand command templates- Generic params, written as Click decorators
vars,imports,functions,includes, shell lines andcli test
What differs from Typer¶
| Feature | With use_click: true |
|---|---|
| Generic params | A string param is a Click decorator such as "@click.option('--loud', is_flag=True)". A Typer signature entry is rejected. |
types |
A plain type (Count: int, Count: int = 1) works with both backends. A full definition is a Click decorator, Loud: "@click.option('--loud', is_flag=True)"; a typer.Option(...) definition is rejected with an error that names the command. |
Inline typer.Option(...) in a shorthand param |
Rejected. Use a Click decorator. |
| List types | --tag: list[str] can be given several times and arrives as a tuple, not a list. |
| Boolean options | --loud: bool = False is a --loud/--no-loud switch, also when it has a short form. |
config.rich_help_panel |
Passed to rich-click as panel. The generated code then requires rich-click. |
--version output |
<program>, version <version> instead of <name>, <version>. |
A manifest that uses something the Click backend cannot express stops with an error such as:
~ error in tools.yaml: command `pack`: param `level` uses types.Level, which is a Typer definition (...)
rich-click is optional¶
The generated module starts with:
try:
import rich_click as click
except ImportError: # plain help output when rich-click is not installed
import click
With rich-click installed the help is formatted with Rich. Without it the same CLI runs on plain
Click, which cliffy always installs. cli build reads this import and ships rich-click with the
built CLI.
Building¶
cli build reads the import of rich_click from the generated code and bundles rich-click instead of
Typer, so the manifest does not have to list it under requires.
Typer notes¶
- Typer depends on Rich, so generated CLIs print styled help and tracebacks without extra setup.
-
Typer adds
--install-completionand--show-completionto every CLI. Turn them off with: -
Anything from the Typer documentation that fits in a function signature or body can be used in
types, generic params andrunscripts.