Advanced Python Automation for Network Engineers
Building a Command-Line Tool with argparse
What you'll learn
- Why hardcoded constants at the top of a script don't scale to a real tool
- How argparse subcommands structure a multi-action CLI
- Config precedence: CLI argument > environment variable > default
- That a token is still never accepted as a CLI argument
Listen to a guided explanation of this lesson.
Spoken narration isn't supported in this browser.
From constants to arguments
Every capstone script had a block like BASE_URL = "..." at the top, hand-edited to change behavior. A real tool takes that from the command line instead.
import argparse
import os
def build_parser():
parser = argparse.ArgumentParser(prog="network-tool")
parser.add_argument(
"--base-url",
default=os.environ.get("AUTOMATION_BASE_URL", "http://127.0.0.1:8767"),
)
subparsers = parser.add_subparsers(dest="command", required=True)
check_parser = subparsers.add_parser("check", help="Check every device's compliance")
check_parser.add_argument("--inventory", default="devices.csv")
check_parser.add_argument("--workers", type=int, default=5)
check_parser.add_argument("--report", default="report.json")
report_parser = subparsers.add_parser("report", help="Summarize an existing report file")
report_parser.add_argument("--report", default="report.json")
return parserTwo subcommands -- check (run the automation engine) and report (read back an existing report) -- not five. add_subparsers() is what makes 'network-tool check' and 'network-tool report' both valid, each with their own arguments.
Config precedence: CLI argument > environment variable > default
# No arguments, no env var set:
args = parser.parse_args(["check"])
print("default base-url:", args.base_url)
# A CLI argument, explicitly passed:
args2 = parser.parse_args(["--base-url", "http://example.com", "check"])
print("CLI-arg base-url:", args2.base_url)default=os.environ.get("AUTOMATION_BASE_URL", "http://127.0.0.1:8767") is what implements the precedence: argparse only falls back to this default when --base-url isn't passed -- and the default itself already checked the environment variable first.
default base-url: http://127.0.0.1:8767
CLI-arg base-url: http://example.com
# separately, with AUTOMATION_BASE_URL=http://from-env.example set:
env-var base-url: http://from-env.exampleReal, verified output across three separate runs — an explicit CLI argument always wins; without one, the environment variable is used; without either, the hardcoded fallback applies.
Running it: real end-to-end output
$ export AUTOMATION_TOKEN=demo-token
$ python -m network_automation.cli check --inventory devices.csv --workers 5 --report report.jsonAUTOMATION_TOKEN is read from the environment inside run_check() -- never a --token argument. A token on the command line would sit in shell history and process listings; an environment variable at least avoids that.
Checked 5 devices
already-compliant: 1
validation-failed: 2
auth-failed: 1
unreachable: 1
Report written to report.json
$ python -m network_automation.cli report --report report.json
SW1: already-compliant -- no change needed
SW2: validation-failed -- missing VLANs: [10]
SW5: auth-failed -- SW5 rejected the credentials
SW3: validation-failed -- missing VLANs: [30]
SW4: unreachable -- SW4 timed outReal, verified output from both subcommands, run for real against this module's mock backend.
Verified: it refuses to run without a token
Running network-tool check with no AUTOMATION_TOKEN set does not fall back to an empty or default credential — it stops immediately, before any connection is attempted.
$ python -m network_automation.cli check --inventory devices.csv
AUTOMATION_TOKEN environment variable is required -- never pass a token on the command lineReal, verified output — exit code 1, a clear message, and no attempt to connect without credentials.
Key takeaways
- argparse subcommands (network-tool check, network-tool report) replace hardcoded constants edited by hand with a real, invokable CLI.
- Config precedence — CLI argument > environment variable > default — verified directly across three separate real runs.
- AUTOMATION_TOKEN is read only from the environment, never accepted as a CLI argument — verified to refuse to run without it.
- Both subcommands were actually run against this module's mock backend, producing the exact output shown.