When writing a command line tool in Python using Typer one can create a CLI with commands and even subcommands. If you define a CLI with only one command the CLI will be optimized such that you do not have to provide the command - let's call this modul cli_a.py:
#!env python
import typer
app = typer.Typer()
@app.command()
def main():
print('This is the output of main')
if __name__ == '__main__':
app()
Now, you can call this CLI like so
$ ./cli_a.py --help
Usage: cli_a.py [OPTIONS]
╭─ 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. │
╰─────────────────────────────────────────────────────────────────────────────╯
and
$ ./cli_a.py
This is the output of main
Notice, that there has to be no command called main!
On the other hand you can have a CLI with multiple commands - let's call this cli_b.py:
#!env python
import typer
app = typer.Typer()
@app.command()
def cmd1():
print('This is the output of cmd1')
@app.command()
def cmd2():
print('This is the output of cmd2')
if __name__ == '__main__':
app()
With the following output:
$ ./cli_b.py --help
Usage: cli_b.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 ──────────────────────────────────────────────────────────────────╮
│ cmd1 │
│ cmd2 │
╰─────────────────────────────────────────────────────────────────────────────╯
In this case you have to provide the command to be called:
$ ./cli_b.py cmd1
This is the output of cmd1
I want to combine these two CLI into one - let's call this super_cli.py:
#!env python
import typer
import cli_a
import cli_b
app = typer.Typer()
app.add_typer(cli_a.app, name='cli_a')
app.add_typer(cli_b.app, name='cli_b')
if __name__ == '__main__':
app()
This behaves as expected for cli_b:
$ ./super_cli.py cli_b cmd1
This is the output of cmd1
But requires an unwanted additional command main on cli_a:
$ ./super_cli.py cli_a main
This is the output of main
How can it be achieved that cli_a is callable without specifying the additional command main?
I was expecting to get
$ ./super_cli.py cli_a
This is the output of main
but I do get
$ ./super_cli.py cli_a
Usage: super_cli.py cli_a [OPTIONS] COMMAND [ARGS]...
Try 'super_cli.py cli_a --help' for help.
╭─ Error ─────────────────────────────────────────────────────────────────────╮
│ Missing command. │
╰─────────────────────────────────────────────────────────────────────────────╯
instead.
typer default commandI found Set the default command in Python Typer CLI