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:
$ python items.py create Wand
Creating item: Wand
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:
$ python users.py create Camila
Creating user: Camila
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
anditems.py
). - Create the main
typer.Typer()
application. - Use
app.add_typer()
to include theapp
fromitems.py
andusers.py
, each of those 2 was also created withtyper.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 theapp
fromusers.py
.items
with all the commands (subcommands) in theapp
fromitems.py
.
Check it:
// Check the help
$ 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
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:
// Check the help for items
$ python main.py items --help
// It shows its own commands (subcommands): create, delete, sell
Usage: main.py items [OPTIONS] COMMAND [ARGS]...
Options:
--help Show this message and exit.
Commands:
create
delete
sell
// Try it
$ python main.py items create Wand
Creating item: Wand
$ python main.py items sell Vase
Selling item: Vase
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:
$ python main.py users --help
Usage: main.py users [OPTIONS] COMMAND [ARGS]...
Options:
--help Show this message and exit.
Commands:
create
delete
// Try it
$ python main.py users create Camila
Creating user: Camila
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.