Skip to content

Add Typer

We'll start with the core idea.

To add a typer.Typer() app inside of another.

Manage items

Let's imagine that you are creating a CLI program to manage items in some distant land.

It could be in an items.py file with this:

import typer

app = typer.Typer()


@app.command()
def create(item: str):
    print(f"Creating item: {item}")


@app.command()
def delete(item: str):
    print(f"Deleting item: {item}")


@app.command()
def sell(item: str):
    print(f"Selling item: {item}")


if __name__ == "__main__":
    app()

And you would use it like:

fast →python items.py create Wand
Creating item: Wand

restart ↻

Manage users

But then you realize that you also have to manage users from your CLI app.

It could be a file users.py with something like:

import typer

app = typer.Typer()


@app.command()
def create(user_name: str):
    print(f"Creating user: {user_name}")


@app.command()
def delete(user_name: str):
    print(f"Deleting user: {user_name}")


if __name__ == "__main__":
    app()

And you would use it like:

fast →python users.py create Camila
Creating user: Camila

restart ↻

Put them together

Both parts are similar. In fact, items.py and users.py both have commands create and delete.

But we need them to be part of the same CLI program.

In this case, as with git remote, we can put them together as subcommands in another typer.Typer() CLI program.

Now create a main.py with:

import typer

import items
import users

app = typer.Typer()
app.add_typer(users.app, name="users")
app.add_typer(items.app, name="items")

if __name__ == "__main__":
    app()

Here's what we do in main.py:

  • Import the other Python modules (the files users.py and items.py).
  • Create the main typer.Typer() application.
  • Use app.add_typer() to include the app from items.py and users.py, each of those 2 was also created with typer.Typer().
  • Define a name with the command that will be used for each of these "sub-Typers" to group their own commands.

And now your CLI program has 2 commands:

  • users: with all of the commands (subcommands) in the app from users.py.
  • items with all the commands (subcommands) in the app from items.py.

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:
items
users

restart ↻

Now you have a CLI program with commands items and users, and they in turn have their own commands (subcommands).

Let's check the items command:

fast →python main.py items --help
Usage: main.py items [OPTIONS] COMMAND [ARGS]...

Options:
--help Show this message and exit.

Commands:
create
delete
sell

python main.py items create Wand
Creating item: Wand

python main.py items sell Vase
Selling item: Vase

restart ↻

Tip

Notice that we are still calling $ python main.py but now we are using the command items.

And now check the command users, with all its subcommands:

fast →python main.py users --help
Usage: main.py users [OPTIONS] COMMAND [ARGS]...

Options:
--help Show this message and exit.

Commands:
create
delete

python main.py users create Camila
Creating user: Camila

restart ↻

Recap

That's the core idea.

You can just create typer.Typer() apps and add them inside one another.

And you can do that with any levels of commands that you want.

Do you need sub-sub-sub-subcommands? Go ahead, create all the typer.Typer()s you need and put them together with app.add_typer().

In the next sections we'll update this with more features, but you already have the core idea.

This way, in the same spirit of Click, Typer applications are composable, each typer.Typer() can be a CLI app by itself, but it can also be added as a command group to another Typer app.

You can ask questions about Typer. Try:
How can I terminate a program?
How to launch applications?
How to add help to CLI argument?