Guide: Adding CLI Commands
ant31box uses typer to build its command-line interface. You can easily extend the default CLI with your own commands and command groups.
Step 1: Create the Command File
First, create a new Python file for your commands. For example, my_app/cli.py.
# my_app/cli.py
from typing import Annotated
import typer
from ant31box.config import config
# It's common to create a typer "sub-application" for a group of related commands
app = typer.Typer(help="Custom commands for my application.")
@app.command()
def hello(
name: Annotated[
str,
typer.Option("--name", "-n", help="The name to greet."),
] = "World",
config_path: Annotated[
str | None,
typer.Option("--config", "-c", help="Path to config file."),
] = None,
) -> None:
"""
A simple command that greets the user and loads configuration.
"""
# Adhere to the DI pattern by loading config explicitly
conf = config(path=config_path)
typer.echo(f"Hello, {name} from env: {conf.app.env}!")
@app.command()
def goodbye(
name: Annotated[str, typer.Argument(help="The name to say goodbye to.")]
):
"""
Says goodbye.
"""
typer.echo(f"Goodbye, {name}!")
@app.command(): This decorator turns a function into a command-line command.typer.Option(...): Defines a command-line option (e.g.,--name).typer.Argument(...): Defines a positional command-line argument.- The function's docstring is automatically used as the help text for the command.
Step 2: Create a Main Entry Point
Create a file run.py in your project root to assemble your CLI. This file will import the commands from ant31box and add your own.
#!/usr/bin/env python3
import typer
# Import command groups from ant31box
from ant31box.cmd.typer.server import app as server_app
from ant31box.cmd.typer.version import app as version_app
from ant31box.cmd.typer.default_config import app as config_app
from ant31box.cmd.typer.seed import app as seed_app
# Import your custom command app
from my_app.cli import app as my_app_cli
# Create a new top-level Typer app
app = typer.Typer(no_args_is_help=True)
# Add the ant31box commands
app.add_typer(server_app, name="server")
app.add_typer(version_app, name="version")
app.add_typer(config_app, name="default-config")
app.add_typer(seed_app, name="seed")
# Add your app as a subcommand
app.add_typer(my_app_cli, name="my-app")
def main():
app()
if __name__ == "__main__":
main()
Step 3: Update Project Entry Point
In your pyproject.toml, point the script entry point to your new run:main function.
# in pyproject.toml
[project.scripts]
my-cli = "run:main"
Step 4: Verify Your Command
You can now verify your command from your terminal after installing your project.
# See the new "my-app" command group listed
my-cli --help
# See your new commands
my-cli my-app --help
# Run the command
my-cli my-app hello --name "Developer"
Output:
Hello, Developer from env: dev!