Tutorial 2: Multi-command App¶
Organize commands with groups and sub-apps for larger CLI surfaces.
Goal¶
Create a CLI with separate domains:
- root commands (
hello) - grouped commands (
admin create-user)
Step 1. Create grouped commands¶
from sayer import Sayer, group, Option
app = Sayer(name="demo", help="Modular CLI")
admin = group("admin", help="Admin operations")
@app.command()
def hello(name: str = Option(...)):
print(f"Hello, {name}!")
@admin.command()
def create_user(email: str = Option(..., help="User email")):
print(f"Created {email}")
app.add_command(admin)
if __name__ == "__main__":
app()
Step 2. Run commands¶
Step 3. Add root callback for shared options¶
from sayer import Option
@app.callback(invoke_without_command=True)
def root(verbose: bool = Option(False, "--verbose", is_flag=True)):
if verbose:
print("Verbose mode enabled")
Step 4. Check command tree¶
Why this matters¶
- Groups make command namespaces explicit.
- Sub-apps and groups support independent modules.
- Callback options can centralize shared flags.
Next¶
- Continue to Tutorial 3
- Read Architecture
- Use How-to: Organize Groups and Sub-apps