Netmiko speaks each vendor’s CLI; NAPALM gives one Python API across Cisco, Juniper, Arista, and more — with structured facts and safe config replace and rollback.
Why: Netmiko sends vendor-specific CLI, but NAPALM abstracts that into one consistent API that returns structured data and supports config replace/merge with rollback — so the same code works across Cisco, Juniper, Arista, and others. When: use NAPALM when you manage mixed vendors or want safe, declarative config changes. Where: it is the foundation many higher-level tools build on.
# pip install napalm
import napalm
driver = napalm.get_network_driver("ios") # or "junos", "eos", "nxos_ssh"
device = driver(hostname="192.168.1.1", username="admin", password="...")
device.open()
facts = device.get_facts() # structured, vendor-neutral
print(facts["hostname"], facts["os_version"], facts["uptime"])
device.close()Why: NAPALM’s getters return the same structured shape regardless of vendor — interfaces, BGP neighbors, ARP, LLDP — so you write monitoring and audit logic once instead of per platform. When: use getters for cross-vendor inventory, health checks, and compliance. Where: no CLI parsing at all — the data is already Python dicts.
device.open()
interfaces = device.get_interfaces() # dict keyed by interface name
for name, i in interfaces.items():
if not i["is_up"]:
print("DOWN:", name)
neighbors = device.get_bgp_neighbors() # same shape on any vendor
arp = device.get_arp_table()
device.close()Why: NAPALM can load a full candidate config, show you a DIFF before you commit, and roll back if something goes wrong — turning risky changes into reviewable, reversible ones. When: use load_replace_candidate + compare_config to preview, then commit or discard. Where: the diff-before-commit step is what makes automated config changes safe enough for production.
device.open()
device.load_replace_candidate(filename="configs/sw1.txt")
diff = device.compare_config() # EXACTLY what will change
print(diff)
if diff:
device.commit_config() # apply it
# ...or device.discard_config() to abort
# device.rollback() reverts to the previous config if needed.
device.close()