Multi-File Applications¶
When your CLI application grows, you can split it into multiple files and modules. This pattern helps maintain clean and organized code structure.
This tutorial will show you how to use add_typer to create sub commands and organize your commands in multiple files.
We will create a simple CLI with the following commands:
versionusers add NAMEusers delete NAME
CLI structure¶
Here is the structure we'll be working with:
mycli/
├── __init__.py
├── main.py
├── users/
│ ├── __init__.py
│ ├── add.py
│ └── delete.py
└── version.py
mycli will be our package, and it will contain the following modules:
main.py: The main module that will import theversionandusersmodules.version.py: A module that will contain theversioncommand.users/: A package that will contain theaddanddeletecommands.
Implementation¶
Let's start implementing our CLI! We'll create the version module, the main module, and the users package.
Version Module (version.py)¶
Let's start by creating the version module. This module will contain the version command.
import typer
app = typer.Typer()
@app.command()
def version():
typer.echo("My CLI Version 1.0")
In this file we are creating a new Typer app instance for the version command. This is not required in single-file applications, but in the case of multi-file applications it will allow us to include this command in the main application using add_typer.
Let's see that next!
Main Module (main.py)¶
The main module will be the entry point of the application. It will import the version module and the users module. We'll see how to implement the user module in the next section.
import typer
from .users import app as users_app
from .version import app as version_app
app = typer.Typer()
app.add_typer(version_app)
app.add_typer(users_app, name="users")
if __name__ == "__main__":
app()
In this module, we import the version and users modules and add them to the main app using add_typer. For the users module, we specify the name as users to group the commands under the users namespace.
Let's now create the users module with the add and delete commands.
Users Add Command (users/add.py)¶
import typer
app = typer.Typer()
@app.command()
def add(name: str):
typer.echo(f"Adding user: {name}")
Like the version module, we create a new Typer app instance for the users/add command. This allows us to include the add command in the users app.
Users Delete Command (users/delete.py)¶
import typer
app = typer.Typer()
@app.command()
def delete(name: str):
typer.echo(f"Deleting user: {name}")
And once again, we create a new Typer app instance for the users/delete command. This allows us to include the delete command in the users app.
Users' app (users/__init__.py)¶
Finally, we need to create an __init__.py file in the users directory to define the users app.
import typer
from .add import app as add_app
from .delete import app as delete_app
app = typer.Typer()
app.add_typer(add_app)
app.add_typer(delete_app)
Similarly to the version module, we create a new Typer app instance for the users module. This allows us to include the add and delete commands in the users app.
Running the Application¶
Now we are ready to run the application!
To run the application, execute the main.py file:
$ python main.py version
My CLI Version 1.0
$ python main.py users add Camila
Adding user: Camila