Lesson 4: Grouping & Subcommands — Organize Like a Pro
 
            Your CLI isn’t just a script anymore — it’s a command suite.
This lesson takes you beyond single-command logic and into the world of:
- ✅ Organized --helpoutput
- ✅ Input safety with mutually exclusive options
- ✅ Scalable command families like git add,git commit,git push
Grouping Arguments — Clean Up Your Help Menu
Use .add_argument_group() to visually separate related options in your help menu — then add a little magic to auto-show help when no input is given.
import argparse
import sys
parser = argparse.ArgumentParser(description="User management CLI")
auth_group = parser.add_argument_group("Authentication Options")
auth_group.add_argument('--username', help="User’s name")
auth_group.add_argument('--password', help="User’s password")
# 🪄 Auto-show help if no arguments were provided
if len(sys.argv) == 1:
    parser.print_help()
    sys.exit(1)
args = parser.parse_args()
✅ Use it when your CLI is meant to guide users
✅ Why it matters: Helpful defaults = fewer support headaches
Mutually Exclusive Groups — Say “Pick One”
Use .add_mutually_exclusive_group() to prevent users from doing conflicting things.
group = parser.add_mutually_exclusive_group()
group.add_argument('--add', action='store_true', help="Add a user")
group.add_argument('--delete', action='store_true', help="Delete a user")
Now if someone tries:
python app.py --add --delete
They get:
error: argument --delete: not allowed with argument --add
✅ Use it when:
- --verbosevs- --quiet
- --encryptvs- --public
- --jsonvs- --csv
✅ Why it matters: Keeps your logic safe and unbreakable
Subcommands — Create a Real Command Suite
Now it gets really powerful. You can build commands like:
python taskcli.py add "Feed the dogs"
python taskcli.py done 2
Each one maps to a different subparser:
parser = argparse.ArgumentParser(description="Task CLI")
subparsers = parser.add_subparsers(dest='command', required=True)
add_parser = subparsers.add_parser('add', help='Add a task')
add_parser.add_argument('title', help='Task title')
done_parser = subparsers.add_parser('done', help='Mark task as done')
done_parser.add_argument('task_id', type=int)
args = parser.parse_args()
if args.command == 'add':
    print(f"✅ Task added: {args.title}")
elif args.command == 'done':
    print(f"✅ Task {args.task_id} marked done")
✅ Use it when:
- You’re building a CLI suite like git,pip,aws, etc.
- You want separate logic per command
- You dream of having argparsegreatness
Recap
| Feature | Use Case | Command Style | 
|---|---|---|
| Argument Group | Clean help sections | --username,--password | 
| Mutually Exclusive Group | Conflict prevention | --addXOR--delete | 
| Subcommands | Multi-tool CLI | taskcli.py add "...",done 3 | 
🔜 Coming Up
Next in Lesson 5:
Advanced Usage — nargs, choices, exclusive groups, custom actions, and more black magic 🧙♂️
And after that:
Final Build — a real mini CLI app using all lessons so far
