Netmiko โ multi-vendor SSH automation
The de-facto Python library for talking to network devices over SSH. Send show commands, push config, and parse output into structured data across Cisco, Arista, Juniper and 100+ device types.
Setup, key commands & run examples
Install Netmiko into a virtualenv. It pulls in Paramiko (SSH) and ntc-templates (TextFSM) for you.
python3 -m venv .venv
source .venv/bin/activate
pip install netmikoConnectHandler opens an SSH session. device_type drives the vendor-specific behaviour (cisco_ios, arista_eos, juniper_junos, etc.).
from netmiko import ConnectHandler
device = {
"device_type": "cisco_ios",
"host": "10.10.1.1",
"username": "admin",
"password": "secret",
# "secret": "enablepass", # for enable mode
}
with ConnectHandler(**device) as conn:
output = conn.send_command("show ip interface brief")
print(output)Pass use_textfsm=True to turn raw 'show' output into a list of dicts using ntc-templates โ no manual regex.
with ConnectHandler(**device) as conn:
rows = conn.send_command("show ip interface brief", use_textfsm=True)
for row in rows:
print(row["interface"], row["ip_address"], row["status"])send_config_set enters config mode, applies a list of commands, then exits. Use save_config() to write to startup.
commands = [
"interface loopback100",
"description managed-by-netmiko",
"ip address 10.99.0.1 255.255.255.255",
]
with ConnectHandler(**device) as conn:
print(conn.send_config_set(commands))
conn.save_config() # write memLoop over an inventory to run the same task fleet-wide. For real concurrency, use Netmiko's ConnectHandler with threads or Nornir.
from netmiko import ConnectHandler
hosts = ["10.10.1.1", "10.10.1.2", "10.10.1.3"]
base = {"device_type": "cisco_ios", "username": "admin", "password": "secret"}
for host in hosts:
with ConnectHandler(host=host, **base) as conn:
print(f"== {host} ==")
print(conn.send_command("show version | include uptime"))Hands-on exercises
Guided practice tasks โ copy the starter snippet, run it against a lab device, and finish the TODO to meet the goal.
Goal: Connect to a lab device, run 'show version', and print only the line containing the uptime.
โธ Reveal reference solution
from netmiko import ConnectHandler
device = {"device_type": "cisco_ios", "host": "10.10.1.1",
"username": "admin", "password": "secret"}
with ConnectHandler(**device) as conn:
out = conn.send_command("show version")
for line in out.splitlines():
if "uptime" in line:
print(line.strip())Goal: Use use_textfsm=True to get structured rows, then print only interfaces that are 'up'.
โธ Reveal reference solution
with ConnectHandler(**device) as conn:
rows = conn.send_command("show ip interface brief", use_textfsm=True)
for r in rows:
if r["status"] == "up":
print(r["interface"], r["ip_address"])Goal: Create Loopback150 with send_config_set, save_config(), then read it back to confirm it exists.
โธ Reveal reference solution
cmds = ["interface loopback150", "ip address 10.99.0.50 255.255.255.255"]
with ConnectHandler(**device) as conn:
conn.send_config_set(cmds)
conn.save_config()
print(conn.send_command("show ip interface brief | include Loopback150"))Goal: Loop over three hosts and collect 'show clock' from each, handling failures gracefully.
โธ Reveal reference solution
hosts = ["10.10.1.1", "10.10.1.2", "10.10.1.3"]
base = {"device_type": "cisco_ios", "username": "admin", "password": "secret"}
for host in hosts:
try:
with ConnectHandler(host=host, **base) as conn:
print(host, conn.send_command("show clock"))
except Exception as e:
print(f"{host} failed: {e}")Checklist โ pitfalls, gotchas & verification
Common pitfalls
- โขWrong device_type โ using cisco_ios for an Arista box garbles prompts and timing.
- โขForgetting enable mode โ add a 'secret' and call conn.enable() for privileged commands.
- โขNot saving config โ send_config_set changes running config only until save_config().
Gotchas to watch
- โขuse_textfsm=True silently returns raw text if no ntc-template matches the command.
- โขsend_command waits for the prompt; long-running commands may need read_timeout tuning.
- โขSequential loops are slow โ use threads or Nornir for real concurrency.
Verify it works
- โขPrint the raw output first to confirm the session and command worked.
- โขAfter a config push, re-read the relevant 'show' command to confirm the change landed.
- โขWrap multi-device runs in try/except and report per-host success or failure.
Netmiko is great for direct, imperative tasks. When you need inventory, concurrency and reusable tasks at scale, pair it with Nornir โ which can use Netmiko as its connection driver.