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:
// Without a CLI argument
$ python main.py
Usage: main.py [OPTIONS] NAME
Try "main.py --help" for help.
Error: Missing argument 'NAME'.
// With the NAME CLI argument
$ python main.py Camila
Hello Camila
// Asking for help
$ 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.
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
:
// 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:
create
delete
// Test the commands
$ python main.py create
Creating user: Hiro Hamada
$ python main.py delete
Deleting user: Hiro Hamada
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:
// Check the help
$ python main.py --help
// Notice the single command create
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
// Try it
$ python main.py create
Creating user: Hiro Hamada
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 more users.
"""
if __name__ == "__main__":
app()
And now the docstring from the callback will be used as the help text:
$ python main.py --help
// Notice the help text from the docstring
Usage: main.py [OPTIONS] COMMAND [ARGS]...
Creates a single user Hiro Hamada.
In the next version it will create 5 more users.
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
// And it still works the same, the callback does nothing
$ python main.py create
Creating user: Hiro Hamada