Languages

Automating Network Devices (Routers & Switches) with Python: A Complete Guide

JGJaya Gupta21 Mar 2023 ยท Updated 04 Oct 2026 ยท 7 min read
Automating Network Devices (Routers & Switches) with Python: A Complete Guide

Quick answer: Automating routers and switches with Python means replacing manual SSH sessions with scripts that connect to devices, run commands, push configuration and parse the results. The practical toolkit is Netmiko for SSH, NAPALM for vendor-neutral configuration and facts, Nornir for running tasks across an inventory in parallel, and Scapy or pySNMP for testing and monitoring.

This guide walks through the four pillars of network automation โ€” configuration, monitoring, testing and visualisation โ€” and shows real code for each. You will see how a single script can audit fifty switches in under a minute, how to push a change safely with a dry-run diff, how to monitor interfaces without a commercial NMS, and the mistakes that turn a helpful script into an outage.

Why automate routers and switches?

A medium-sized campus has 200 access switches. Adding one VLAN by hand means 200 logins, 200 chances for a typo, and a change window that stretches across a weekend. The same change in Python is one template, one inventory file and a few minutes of runtime, with a log of exactly what happened on every device.

Beyond speed, automation gives you idempotency (run the script twice, get the same result), auditability (scripts and templates live in Git) and repeatable validation (the same checks run before and after every change). For the broader case, see Why Use Python for Network Engineering?.

The Python network automation toolkit

Library Purpose Protocol Vendor support
Netmiko Send show and config commands over SSH SSH, Telnet Cisco, Juniper, Arista, HP, Fortinet and many more
NAPALM Vendor-neutral getters (facts, interfaces, BGP) and config replace/merge with diff SSH, NETCONF, eAPI IOS, IOS-XR, NX-OS, Junos, EOS
Nornir Inventory and parallel task runner; plugs in Netmiko or NAPALM Any Any
ncclient / Scrapli NETCONF and fast SSH with structured YANG data NETCONF, SSH Modern IOS-XE, Junos, IOS-XR
pySNMP Poll counters and traps SNMP v2c/v3 Everything
Scapy Craft, send and sniff packets Raw N/A
NetworkX + Matplotlib Build and draw topology graphs N/A N/A

Install the core set in a virtual environment: python -m venv venv && source venv/bin/activate && pip install netmiko napalm nornir nornir-netmiko.

Pillar 1 โ€“ Configuration: pushing changes safely

The simplest approach uses Netmiko’s send_config_set(). Credentials come from environment variables so the script can be committed to Git without leaking anything.

import os
from netmiko import ConnectHandler

switch = {
    "device_type": "cisco_ios",
    "host": "10.10.1.11",
    "username": os.environ["NET_USER"],
    "password": os.environ["NET_PASS"],
    "secret": os.environ.get("NET_ENABLE", ""),
}

vlan_config = [
    "vlan 120",
    " name GUEST-WIFI",
    "interface range GigabitEthernet1/0/1 - 24",
    " switchport trunk allowed vlan add 120",
]

with ConnectHandler(**switch) as conn:
    conn.enable()
    output = conn.send_config_set(vlan_config)
    print(output)
    conn.save_config()           # write memory / copy run start

For anything beyond a handful of lines, NAPALM is safer because it shows you a diff before committing. Here the script loads a candidate configuration, prints the diff, and only commits if a human types yes:

import os
from napalm import get_network_driver

driver = get_network_driver("ios")
device = driver(
    hostname="10.10.1.11",
    username=os.environ["NET_USER"],
    password=os.environ["NET_PASS"],
    optional_args={"secret": os.environ.get("NET_ENABLE", "")},
)

device.open()
device.load_merge_candidate(filename="vlan120.cfg")
diff = device.compare_config()

if not diff:
    print("No changes needed")
    device.discard_config()
elif input(f"{diff}\nApply? (yes/no) ") == "yes":
    device.commit_config()
    print("Committed")
else:
    device.discard_config()
device.close()

Scaling to the whole estate is Nornir’s job: define hosts in inventory/hosts.yaml, and nr.run(task=netmiko_send_config, config_commands=vlan_config) executes against every device concurrently, collecting per-host results and failures.

Pillar 2 โ€“ Monitoring: knowing before users complain

You do not need a commercial NMS to catch the basics. NAPALM’s get_interfaces_counters() returns a dictionary per interface with error counts, so a script that runs every five minutes from cron can alert on rising CRC errors:

import json, os, pathlib
from napalm import get_network_driver

STATE = pathlib.Path("counters.json")
previous = json.loads(STATE.read_text()) if STATE.exists() else {}

driver = get_network_driver("ios")
with driver("10.10.1.1", os.environ["NET_USER"], os.environ["NET_PASS"]) as dev:
    current = dev.get_interfaces_counters()

for name, counters in current.items():
    old = previous.get(name, {}).get("rx_errors", 0)
    delta = counters["rx_errors"] - old
    if delta > 50:
        print(f"ALERT {name}: {delta} new input errors in the last interval")

STATE.write_text(json.dumps(current))

Swap the print for a webhook call to Slack, Teams or PagerDuty and you have a lightweight alerting system. For devices that only speak SNMP, pysnmp can poll ifInErrors (OID 1.3.6.1.2.1.2.2.1.14) the same way.

Pillar 3 โ€“ Testing: proving the network does what you think

Automated tests catch regressions after a change window. Common patterns:

  • Pre/post snapshots. Save get_bgp_neighbors(), get_arp_table() and get_interfaces() output before the change, repeat after, and diff them. If a BGP neighbour went down, the script fails loudly.
  • Reachability tests. Use Netmiko to run ping from the device itself, or run pytest on your laptop with assertions against NAPALM getters.
  • ACL and firewall validation. Scapy can craft a TCP SYN to port 445 from a specific source and confirm it is dropped in a lab.
  • Port scanning. python-nmap wraps Nmap so you can check that management interfaces expose only SSH and not Telnet or HTTP.

Pillar 4 โ€“ Visualisation: seeing the topology

Discovery protocols already know your topology. Collect show cdp neighbors detail or show lldp neighbors from every device with Netmiko’s use_textfsm=True, add each pair as an edge in a NetworkX graph, and draw it with Matplotlib. The full walkthrough, including colour-coding by device role, is in Network Visualization with Matplotlib and NetworkX.

Seven automation mistakes that cause outages

  1. No dry run. Pushing config to 200 devices without looking at a diff on one first. Always pilot on a single device, then a small group, then everything.
  2. Hard-coded credentials. Use environment variables, getpass, or a vault such as HashiCorp Vault or AWS Secrets Manager.
  3. Ignoring failures mid-run. If device 37 times out and the script keeps going, you now have an inconsistent network. Catch NetmikoTimeoutException and NetmikoAuthenticationException, log them, and decide deliberately whether to continue.
  4. Forgetting to save. send_config_set() changes the running config only. Call save_config() or a reload erases your work.
  5. Parsing with fragile string slicing. Use TextFSM templates, NAPALM getters or regular expressions that tolerate whitespace changes between software versions.
  6. Locking yourself out. Changing the management VLAN or ACL on the interface you are connected through drops the session before the script can save. Use reload in 10 as a safety net on IOS, or NAPALM’s commit_config(revert_in=...) where supported.
  7. Treating automation as a side project. Scripts without version control, code review and a lab are technical debt. Treat them like production software.

Frequently asked questions

Should I use Netmiko, NAPALM or Nornir?

Use Netmiko when you need to send arbitrary CLI commands. Use NAPALM when you want structured data and diff-based config changes across vendors. Use Nornir to run either of them against many devices with a proper inventory. Most teams use all three together.

Can I automate devices that only support Telnet?

Yes, Netmiko supports device_type values ending in _telnet, such as cisco_ios_telnet. Treat it as a stop-gap: Telnet is unencrypted, so the real fix is enabling SSH on those devices.

Do I need a lab to practise?

Strongly recommended. Cisco Modeling Labs, EVE-NG, GNS3 and Containerlab all run on a laptop, and the Cisco DevNet Sandbox offers free always-on devices you can reach over the internet.

How does this compare with Ansible?

Ansible is declarative and excellent for standard tasks with existing modules. Python gives you full control for custom logic, parsing and API integration. Ansible’s network modules are themselves written in Python, so the knowledge transfers directly.

Key takeaways

  • Network automation rests on four pillars: configuration, monitoring, testing and visualisation โ€” Python has mature libraries for each.
  • Netmiko for CLI, NAPALM for diffs and structured facts, Nornir for scale.
  • Always pilot, diff and save; handle failures explicitly.
  • Keep credentials out of code and scripts in Git with a lab to test against.

Want to go from running single scripts to building a full automation workflow with inventories, templates and tests? Our Python & Data Science course takes you from Python fundamentals to real projects, with mentor support and placement assistance. Watch live lab demonstrations on our YouTube channel.

JG
Written byJaya Gupta

Part of the Techknowledgehub team of industry mentors, writing practical guides to help you build a job-ready tech career.

More articles by Jaya Gupta โ†’
Keep reading

Related articles

M# Programming Language
Languages

M# Programming Language

What the M# programming language really is, how its declarative models generate C# and ASP.NET Core code, who uses it,โ€ฆ

01 Apr 2023ยท 8 min read

Leave a Reply