Skip to content

One or Multiple Commands

You might have noticed that if you create a single command, as in the first example:

import typer

app = typer.Typer()


@app.command()
def main(name: str):
    print(f"Hello {name}")


if __name__ == "__main__":
    app()

Typer is smart enough to create a CLI application with that single function as the main CLI application, not as a command/subcommand:

fast β†’python main.py
Usage: main.py [OPTIONS] NAME
Try "main.py --help" for help.

Error: Missing argument 'NAME'.

python main.py Camila
Hello Camila

python main.py
Usage: main.py [OPTIONS] NAME

Options:
--install-completion Install completion for the current shell.
--show-completion Show completion for the current shell, to copy it or customize the installation.
--help Show this message and exit.

restart ↻

Tip

Notice that it doesn't show a command main, even though the function name is main.

But if you add multiple commands, Typer will create one CLI command for each one of them:

import typer

app = typer.Typer()


@app.command()
def create():
    print("Creating user: Hiro Hamada")


@app.command()
def delete():
    print("Deleting user: Hiro Hamada")


if __name__ == "__main__":
    app()

Here we have 2 commands create and delete:

fast β†’python main.py --help
Usage: main.py [OPTIONS] COMMAND [ARGS]...

Options:
--install-completion Install completion for the current shell.
--show-completion Show completion for the current shell, to copy it or customize the installation.
--help Show this message and exit.

Commands:
create
delete

python main.py create
Creating user: Hiro Hamada

python main.py delete
Deleting user: Hiro Hamada

restart ↻

One command and one callbackΒΆ

If you want to create a CLI app with one single command but you still want it to be a command/subcommand you can just add a callback:

import typer

app = typer.Typer()


@app.command()
def create():
    print("Creating user: Hiro Hamada")


@app.callback()
def callback():
    pass


if __name__ == "__main__":
    app()

And now your CLI program will have a single command.

Check it:

fast β†’python main.py --help
Usage: main.py [OPTIONS] COMMAND [ARGS]...

Options:
--install-completion Install completion for the current shell.
--show-completion Show completion for the current shell, to copy it or customize the installation.
--help Show this message and exit.

Commands:
create

python main.py create
Creating user: Hiro Hamada

restart ↻

Using the callback to documentΒΆ

Now that you are using a callback just to have a single command, you might as well use it to add documentation for your app:

import typer

app = typer.Typer()


@app.command()
def create():
    print("Creating user: Hiro Hamada")


@app.callback()
def callback():
    """
    Creates a single user Hiro Hamada.

    In the next version it will create 5 users more.
    """


if __name__ == "__main__":
    app()

And now the docstring from the callback will be used as the help text:

fast β†’python main.py --help
Usage: main.py [OPTIONS] COMMAND [ARGS]...

Creates a single user Hiro Hamada.

In the next version it will create 5 users more.

Options:
--install-completion Install completion for the current shell.
--show-completion Show completion for the current shell, to copy it or customize the installation.
--help Show this message and exit.

Commands:
create

python main.py create
Creating user: Hiro Hamada

restart ↻