CLI output is text meant for humans. Turn "show" commands into structured data your code can filter and act on — the key to real automation.
Why: device output is formatted for human eyes, so writing fragile string-splitting to extract a field breaks the moment the output shifts — structured parsing turns text into lists of dictionaries you can reliably work with. When: any time you need to make a decision based on device state (which interfaces are down, which have errors). Where: TextFSM templates (via ntc-templates) do this for hundreds of commands.
pip install netmiko ntc-templatesWhy: passing use_textfsm=True to send_command returns parsed, structured data instead of a wall of text — so you get fields by name rather than by fragile string position. When: use it whenever you need specific values out of show output. Where: ntc-templates ships community TextFSM templates, so most common commands parse with no extra work.
from netmiko import ConnectHandler
with ConnectHandler(**device) as conn:
# use_textfsm returns a list of dicts instead of raw text:
rows = conn.send_command("show ip interface brief", use_textfsm=True)
for row in rows:
print(row["interface"], row["ip_address"], row["status"])
# [{'interface': 'Gig0/0', 'ip_address': '10.0.0.1', 'status': 'up', ...}, ...]Why: once output is structured, automation becomes real — you filter, count, and decide in code, turning "eyeball 200 interfaces" into a one-line audit. When: build health checks and audits that flag exactly the devices or interfaces that need attention. Where: this same pattern (collect → parse → decide) underlies every monitoring and compliance script.
with ConnectHandler(**device) as conn:
rows = conn.send_command("show ip interface brief", use_textfsm=True)
# Which interfaces are administratively down?
down = [r["interface"] for r in rows if r["status"] == "administratively down"]
print("shut interfaces:", down)
# Automated audit: fail if any uplink is down.
uplinks = {"Gig0/0", "Gig0/1"}
assert not (uplinks & set(down)), f"Uplink down: {uplinks & set(down)}"