I built Unix-friendly Python CLIs with argparse subcommands, validated arguments, and meaningful exit codes. Following CLI conventions made the tools composable in shell pipelines and reliable in CI, where exit status drives control flow.

Objective & Context

A good CLI is predictable: clear help, validated input, and a non-zero exit on failure. This lab uses argparse subparsers and returns proper exit codes so scripts behave correctly under set -e and in automated pipelines.

Environment & Prerequisites

  • Python 3.11 with argparse (standard library).
  • A shell to test piping and exit codes.
  • A task with at least two subcommands.

Step-by-Step Execution

1. Define subcommands

import argparse, sys
p = argparse.ArgumentParser(prog="tyfctl")
sub = p.add_subparsers(dest="cmd", required=True)
sub.add_parser("scan").add_argument("target")
args = p.parse_args()

2. Return a meaningful exit code

python tyfctl.py scan 192.168.20.0/24; echo "exit=$?"

3. Confirm generated help

python tyfctl.py --help
usage: tyfctl [-h] {scan,report} ...
exit=0

Validation & Testing

Run each subcommand with valid and invalid arguments and check the exit code in the shell. Pass criteria: usage errors exit non-zero with help, success exits 0, and the tool reads stdin/writes stdout cleanly for piping.

Advanced: Troubleshooting
  • Always exits 0: call sys.exit(code) explicitly on failure paths.
  • Broken pipes: handle BrokenPipeError when output is piped to head.
  • Unclear errors: let argparse handle validation; it prints usage and exits 2.

Key Results

  • Shipped CLIs with subcommands and auto-generated help.
  • Returned correct exit codes for clean CI/pipeline integration.
  • Validated arguments declaratively via argparse.
  • Made tools composable through stdin/stdout conventions.