Python for Network Engineers

1. Why Python for Network Engineering?

Network engineers have traditionally managed devices one at a time — logging in via SSH or console, typing commands, reading output, and repeating the process across dozens or hundreds of devices. This manual approach is slow, error-prone, and does not scale. Python has become the dominant scripting language for network automation because it is readable, powerful, and supported by a rich ecosystem of networking libraries that handle SSH connections, vendor abstraction, data parsing, and API interaction out of the box.

The shift toward network automation aligns with the network automation and controller-based networking trends that are now core topics in the CCNA curriculum. Understanding Python fundamentals and key networking libraries is an expected baseline skill for modern network engineers.

Manual CLI Approach Python Automation Approach
Log into each device individually — one at a time Script iterates a device list and connects to all in a loop
Type the same commands on every device Commands defined once in a variable or template; applied consistently to all devices
Read output visually — human error possible Output parsed programmatically — results extracted and compared to expected values
Changes on 100 devices take hours Changes on 100 devices take seconds to minutes
No automatic logging or audit trail All commands and outputs logged to file automatically
Inconsistency — every engineer types slightly differently Identical configuration applied every time from the same source code

1.1 Python vs Other Automation Options

Tool / Language Strength Best Use Case
Python Flexible; huge library ecosystem; universal network support; easy to learn Custom scripts; data parsing; API integration; complex logic
Ansible Agentless; YAML-based (no programming required); idempotent modules; Cisco IOS/NX-OS/ASA modules built-in Bulk configuration deployment; desired-state enforcement; playbook-based workflows
Bash / shell scripts Lightweight; always available on Linux/macOS Simple file manipulation; invoking other tools; quick one-liners
Terraform Infrastructure-as-code; declarative; multi-cloud support Cloud infrastructure provisioning; virtualised network functions

Related pages: Network Automation Overview | Ansible Overview | Controller-Based Networking | Northbound & Southbound APIs | JSON, XML & YANG | NETCONF & RESTCONF | Netmiko Show Commands Lab | NAPALM Multi-Vendor Lab | NETCONF with Python (ncclient) Lab | Jinja2 Config Generation Lab

2. Python Networking Library Landscape

The Python ecosystem for networking is rich and layered. Libraries exist at every level — from raw SSH transport up to high-level vendor-agnostic abstraction. Understanding which library solves which problem prevents reinventing the wheel.

Library Layer / Purpose Key Feature Install
Paramiko SSH transport (low-level) Pure Python SSH2 implementation; low-level control over SSH channels and sessions; Netmiko is built on top of it pip install paramiko
Netmiko SSH automation (mid-level) Handles SSH quirks of 50+ network vendor platforms (Cisco IOS, NX-OS, EOS, Junos, etc.); auto-detects prompts; sends commands and returns output; built for network engineers pip install netmiko
NAPALM Multi-vendor abstraction (high-level) Vendor-neutral API for get/configure operations across IOS, NX-OS, EOS, Junos, IOS-XR; returns structured Python dictionaries; supports config diff and merge pip install napalm
TextFSM Output parsing Template-based parser that converts unstructured CLI output (show commands) into structured Python lists/dicts using regex templates (NTC-Templates library) pip install textfsm
nornir Automation framework Python-native automation framework (Ansible alternative); uses inventory files; runs tasks in parallel; integrates with Netmiko, NAPALM, and other plugins pip install nornir
requests HTTP/REST API client HTTP GET/POST/PUT/DELETE for REST APIs (Cisco DNA Center, Meraki, NSO, SD-WAN vManage); returns JSON responses pip install requests
ncclient NETCONF client Implements NETCONF protocol (RFC 6241) for structured device configuration and state retrieval using XML/YANG pip install ncclient
pyATS / Genie Testing framework Cisco's test and validation framework; Genie parsers provide structured output for hundreds of show commands; used for network validation and CI/CD pipelines pip install pyats genie

3. Netmiko – SSH Automation for Network Devices

Netmiko (developed by Kirk Byers) is the most widely used Python library for SSH-based network automation. It solves the frustrating problem that raw Paramiko SSH sessions require manual handling of every router's unique prompt behaviour, pagination, error messages, and timing. Netmiko abstracts all of this — you specify the device type and Netmiko handles the rest.

3.1 What Netmiko Does Automatically

Challenge with Raw SSH How Netmiko Handles It
Different prompt patterns per vendor (Router# vs Switch> vs hostname@) Device type parameter triggers the correct prompt regex pattern for each vendor's CLI
Pagination — --More-- after 24 lines of output Automatically disables pagination with terminal length 0 (Cisco) or equivalent on login
Timing — need to wait for command output before sending next command Waits for the prompt to return before proceeding; handles slow or high-latency devices
Enable mode — need to enter enable and provide password Automatically enters enable mode using the secret parameter
Config mode — need to enter configure terminal before making changes send_config_set() automatically enters and exits config mode around the supplied commands
SSH key fingerprint acceptance Handles host key acceptance automatically

3.2 Netmiko Supported Device Types (Selected)

Device Type String Vendor / OS
cisco_ios Cisco IOS and IOS-XE routers and switches
cisco_nxos Cisco Nexus (NX-OS)
cisco_asa Cisco ASA firewall
cisco_xr Cisco IOS-XR (ASR 9000, NCS)
arista_eos Arista EOS switches
juniper_junos Juniper Junos routers and switches
hp_procurve HP ProCurve / Aruba switches
linux Linux servers (useful for network function VMs)

3.3 Core Netmiko Methods

Method Purpose Returns
ConnectHandler(**device) Establishes the SSH connection to the device Connection object
send_command(cmd) Sends a single show command and waits for the prompt to return String — full command output
send_command(cmd, use_textfsm=True) Sends a show command and parses output with TextFSM using NTC-Templates List of dicts — structured data
send_config_set(commands) Enters config mode, sends a list of configuration commands, exits config mode String — command echoes and any output
save_config() Saves the running configuration (write memory or equivalent) String — confirmation output
disconnect() Closes the SSH session cleanly None
find_prompt() Returns the current CLI prompt — useful for verifying connection state String — current prompt (e.g., Router#)

4. Simple Show-Command Script with Netmiko

The following scripts demonstrate practical Netmiko patterns — from the simplest single-device connection to a multi-device loop that collects interface information across a fleet.

4.1 Script 1 – Connect and Run a Single Show Command

#!/usr/bin/env python3
"""
Script 1: Connect to a Cisco IOS device via SSH and retrieve
the output of 'show version'.
"""

from netmiko import ConnectHandler

# Device connection dictionary
device = {
    "device_type": "cisco_ios",
    "host":        "192.168.1.1",
    "username":    "admin",
    "password":    "cisco123",
    "secret":      "enable123",    # Enable password
}

# Establish connection
connection = ConnectHandler(**device)

# Enter enable mode (if not already in it)
connection.enable()

# Send the show command and capture output
output = connection.send_command("show version")

# Print the raw output
print(output)

# Clean up the SSH session
connection.disconnect()
print("Connection closed.")

4.2 Script 2 – Multi-Device Loop with show ip interface brief

#!/usr/bin/env python3
"""
Script 2: Connect to multiple Cisco IOS devices, run
'show ip interface brief', and print per-device results.
"""

from netmiko import ConnectHandler

# List of devices to automate
devices = [
    {"device_type": "cisco_ios", "host": "10.0.0.1",
     "username": "admin", "password": "cisco123", "secret": "enable123"},
    {"device_type": "cisco_ios", "host": "10.0.0.2",
     "username": "admin", "password": "cisco123", "secret": "enable123"},
    {"device_type": "cisco_ios", "host": "10.0.0.3",
     "username": "admin", "password": "cisco123", "secret": "enable123"},
]

command = "show ip interface brief"

# Iterate over every device
for device in devices:
    print(f"\n{'='*60}")
    print(f"Connecting to {device['host']}...")

    try:
        conn = ConnectHandler(**device)
        conn.enable()
        hostname = conn.find_prompt().replace("#", "")  # Extract hostname
        output   = conn.send_command(command)
        conn.disconnect()

        print(f"Hostname: {hostname}")
        print(output)

    except Exception as e:
        print(f"ERROR connecting to {device['host']}: {e}")

print("\nAll devices processed.")

4.3 Script 3 – Structured Output with TextFSM Parsing

#!/usr/bin/env python3
"""
Script 3: Run 'show ip interface brief' and use TextFSM
(via use_textfsm=True) to get structured data as a list
of Python dictionaries instead of raw string output.
Requires: pip install netmiko ntc_templates
"""

from netmiko import ConnectHandler
import json

device = {
    "device_type": "cisco_ios",
    "host":        "192.168.1.1",
    "username":    "admin",
    "password":    "cisco123",
    "secret":      "enable123",
}

conn = ConnectHandler(**device)
conn.enable()

# use_textfsm=True triggers TextFSM parsing via NTC-Templates
interfaces = conn.send_command(
    "show ip interface brief",
    use_textfsm=True
)

conn.disconnect()

# 'interfaces' is now a list of dicts — one per interface
print(f"Found {len(interfaces)} interfaces:\n")
for intf in interfaces:
    print(f"  Interface: {intf['intf']:<20} "
          f"IP: {intf['ipaddr']:<16} "
          f"Status: {intf['status']:<10} "
          f"Protocol: {intf['proto']}")

# Pretty-print the full structured data as JSON
print("\nFull structured output:")
print(json.dumps(interfaces, indent=2))

4.4 Script 4 – Push Configuration Changes

#!/usr/bin/env python3
"""
Script 4: Push a list of configuration commands to a device.
Adds a loopback interface, sets a description, and saves.
"""

from netmiko import ConnectHandler

device = {
    "device_type": "cisco_ios",
    "host":        "192.168.1.1",
    "username":    "admin",
    "password":    "cisco123",
    "secret":      "enable123",
}

# Configuration commands to apply
config_commands = [
    "interface Loopback99",
    "description Managed by Python Automation",
    "ip address 10.99.99.1 255.255.255.255",
    "no shutdown",
]

conn = ConnectHandler(**device)
conn.enable()

# send_config_set enters config mode, applies all commands, exits
output = conn.send_config_set(config_commands)
print("Configuration output:")
print(output)

# Save the running configuration
save_output = conn.save_config()
print("\nSave output:")
print(save_output)

conn.disconnect()
print("Configuration applied and saved.")

5. NAPALM – Network Automation and Programmability Abstraction Layer with Multivendor support

NAPALM (Network Automation and Programmability Abstraction Layer with Multivendor support) is a Python library that provides a unified, vendor-neutral API for interacting with network devices. Where Netmiko gives you SSH access with vendor-aware prompt handling, NAPALM goes further — it defines a common set of methods that work identically across different vendor platforms, returning structured Python data regardless of vendor.

The key value proposition: you write your automation code once using NAPALM's standard API, and it works against a Cisco IOS router, an Arista EOS switch, and a Juniper router without changing a single line of business logic — only the driver parameter changes.

5.1 NAPALM Supported Drivers

Driver Name Vendor / OS Transport Used
ios Cisco IOS and IOS-XE SSH (via Netmiko)
nxos Cisco NX-OS NX-API (HTTP/HTTPS)
nxos_ssh Cisco NX-OS SSH (via Netmiko)
iosxr Cisco IOS-XR SSH (via Netmiko)
eos Arista EOS eAPI (HTTP/HTTPS)
junos Juniper JunOS NETCONF (via ncclient)

5.2 NAPALM Core Get Methods

NAPALM's getter methods provide structured data in Python dictionaries — no parsing required. Every getter works the same way on every supported platform:

NAPALM Getter What It Returns Equivalent CLI Command (IOS)
get_facts() Hostname, FQDN, vendor, model, OS version, serial number, uptime, interface list show version
get_interfaces() Per-interface details — MAC, speed, MTU, description, is_up, is_enabled, last_flapped show interfaces
get_interfaces_ip() IP addresses per interface with prefix length show ip interface brief
get_bgp_neighbors() BGP neighbour state, ASN, uptime, prefix counts show bgp summary
get_arp_table() ARP table entries — IP, MAC, interface, age show arp
get_route_to(destination) Routing table entry for a specific destination show ip route <dst>
get_snmp_information() SNMP community strings, contact, location show snmp
get_config(retrieve="all") Running, startup, and/or candidate configuration show running-config
get_vlans() VLAN database — VLAN IDs, names, associated interfaces show vlan
get_lldp_neighbors() LLDP neighbour table — port, hostname, interface show lldp neighbors

5.3 NAPALM Configuration Management

NAPALM Method Purpose
load_merge_candidate(config=…) Load new config that will be merged into the running configuration (adds to existing config)
load_replace_candidate(config=…) Load new config that will replace the entire running configuration (full replacement — use with care)
compare_config() Returns a diff showing what would change — lets you review before committing; extremely useful for change management
commit_config() Applies the loaded candidate configuration to the device
rollback() Reverts to the previous configuration — available on platforms that support configuration rollback (EOS, Junos, IOS-XR); limited on classic IOS
discard_config() Cancels a loaded candidate without applying it

6. Simple NAPALM Scripts

6.1 Script 5 – Collect Facts with NAPALM

#!/usr/bin/env python3
"""
Script 5: Use NAPALM to collect structured device facts from
a Cisco IOS device. The same code works for Arista EOS or
Juniper JunOS by changing only the driver name.
Requires: pip install napalm
"""

import napalm
import json

# Select the correct driver for the vendor
driver = napalm.get_network_driver("ios")   # Change to "eos" or "junos" etc.

# Connect to the device
device = driver(
    hostname  = "192.168.1.1",
    username  = "admin",
    password  = "cisco123",
    optional_args = {"secret": "enable123"},  # IOS enable password
)

device.open()

# Collect structured facts — same method on every vendor
facts = device.get_facts()
print("=== Device Facts ===")
print(json.dumps(facts, indent=2))

# Collect interface IP addresses
interfaces_ip = device.get_interfaces_ip()
print("\n=== Interface IP Addresses ===")
print(json.dumps(interfaces_ip, indent=2))

device.close()
print("\nConnection closed.")

6.2 Script 6 – Preview Config Changes with NAPALM Diff

#!/usr/bin/env python3
"""
Script 6: Use NAPALM's compare_config() to preview what will
change on the device before committing — a safe change
management workflow.
"""

import napalm

driver = napalm.get_network_driver("ios")

device = driver(
    hostname      = "192.168.1.1",
    username      = "admin",
    password      = "cisco123",
    optional_args = {"secret": "enable123"},
)

device.open()

# New configuration snippet to merge in
new_config = """
interface Loopback100
 description Managed by NAPALM
 ip address 10.100.100.1 255.255.255.255
 no shutdown
"""

# Load as a merge candidate (non-destructive — adds to existing config)
device.load_merge_candidate(config=new_config)

# Review the diff BEFORE committing
diff = device.compare_config()
if diff:
    print("=== Configuration Diff (+ = add, - = remove) ===")
    print(diff)

    # Only commit if the diff looks correct
    confirm = input("\nCommit this change? (yes/no): ")
    if confirm.lower() == "yes":
        device.commit_config()
        print("Configuration committed.")
    else:
        device.discard_config()
        print("Changes discarded — device unchanged.")
else:
    print("No changes detected — device already in desired state.")
    device.discard_config()

device.close()

6.3 Script 7 – Multi-Vendor Inventory Script

#!/usr/bin/env python3
"""
Script 7: Collect hostname, model, and OS version from a
mixed-vendor fleet (Cisco IOS + Arista EOS) using the same
NAPALM get_facts() call — vendor-agnostic code.
"""

import napalm
import json

# Mixed-vendor device inventory
inventory = [
    {"driver": "ios",  "host": "10.0.0.1",
     "username": "admin", "password": "cisco123",
     "optional_args": {"secret": "enable123"}},
    {"driver": "ios",  "host": "10.0.0.2",
     "username": "admin", "password": "cisco123",
     "optional_args": {"secret": "enable123"}},
    {"driver": "eos",  "host": "10.0.0.3",
     "username": "admin", "password": "arista123",
     "optional_args": {}},
]

results = []

for entry in inventory:
    driver_name = entry.pop("driver")   # Extract driver name
    drv = napalm.get_network_driver(driver_name)
    dev = drv(**entry)

    try:
        dev.open()
        facts = dev.get_facts()
        results.append({
            "host":     entry["host"],
            "vendor":   facts["vendor"],
            "hostname": facts["hostname"],
            "model":    facts["model"],
            "os_version": facts["os_version"],
        })
        dev.close()
    except Exception as e:
        results.append({"host": entry["host"], "error": str(e)})

# Print summary table
print(f"\n{'Host':<15} {'Vendor':<10} {'Hostname':<20} "
      f"{'Model':<20} {'OS Version'}")
print("-" * 85)
for r in results:
    if "error" in r:
        print(f"{r['host']:<15} ERROR: {r['error']}")
    else:
        print(f"{r['host']:<15} {r['vendor']:<10} {r['hostname']:<20} "
              f"{r['model']:<20} {r['os_version']}")

7. Netmiko vs NAPALM – When to Use Each

Dimension Netmiko NAPALM
Abstraction level Mid-level — vendor-aware SSH; returns raw CLI string output High-level — vendor-neutral API; returns structured Python dicts
Output format Raw string (unless use_textfsm=True is used) Always structured Python dictionaries — no parsing needed
Vendor coverage 50+ vendor platforms; any device with SSH CLI access 6 core platforms (IOS, NX-OS, IOS-XR, EOS, JunOS); community drivers extend this
Config management Sends raw config commands; no native diff or rollback load/compare/commit/rollback workflow — supports safe config change management
Arbitrary commands Yes — any command the device accepts can be sent Limited to defined getters; for arbitrary commands must drop to Netmiko or use cli() method
Transport SSH only SSH, NETCONF, or HTTP API depending on driver and vendor
Best for Ad-hoc troubleshooting scripts; collecting any show command output; sending config to many devices quickly; legacy or unusual vendors Multi-vendor automation where structured data is needed; network-wide inventory collection; safe config management with diff preview

8. Output Parsing – TextFSM and NTC-Templates

A critical challenge in SSH-based automation is converting the unstructured text output of CLI show commands into structured data (lists, dictionaries) that Python can process programmatically. Two primary approaches exist:

Parsing Method How It Works Pros Cons
Manual string parsing (split / regex) Python str.split(), str.find(), or re module applied directly to the output string No dependencies; maximum flexibility Fragile — breaks if output format changes; must write and maintain parser for every command on every vendor
TextFSM + NTC-Templates Template-based parser using regular expression grammars; NTC-Templates provides pre-built templates for hundreds of Cisco/Arista/Juniper show commands; Netmiko integrates automatically with use_textfsm=True No regex writing needed; community-maintained; returns consistent structured dicts Limited to supported commands in the NTC-Templates library; templates must be maintained as IOS output changes
NAPALM getters Vendor abstraction layer handles parsing internally — the getter method returns structured data regardless of vendor CLI differences Zero parsing code; fully structured; vendor-neutral Limited to the specific getters NAPALM defines; cannot retrieve arbitrary show command data
Genie (pyATS) Cisco's Genie library provides structured parsers for thousands of show commands across IOS, NX-OS, EOS, and more; integrates with pyATS test framework Extremely comprehensive; official Cisco support Heavier dependency; primarily for Cisco platforms

9. Python Environment Setup for Network Automation

Before running any of the scripts on this page, you need a properly configured Python environment. Here is the recommended setup:

9.1 Install Python and Create a Virtual Environment

# Verify Python 3.8+ is installed
python3 --version

# Create a virtual environment (keeps project dependencies isolated)
python3 -m venv netauto-env

# Activate the virtual environment
# On macOS/Linux:
source netauto-env/bin/activate

# On Windows:
netauto-env\Scripts\activate

# Your prompt changes to show (netauto-env) when active

9.2 Install Networking Libraries

# Install Netmiko and TextFSM support (NTC-Templates)
pip install netmiko ntc_templates

# Install NAPALM (includes IOS, NX-OS, EOS, JunOS drivers)
pip install napalm

# Install requests (for REST API interaction)
pip install requests

# Install nornir (automation framework — optional)
pip install nornir nornir-netmiko nornir-napalm

# Freeze current versions to requirements.txt for reproducibility
pip freeze > requirements.txt

# Reinstall from requirements.txt on another system:
pip install -r requirements.txt

9.3 Best Practices for Credentials

Never hard-code credentials directly in scripts. Use one of these approaches:

Approach How It Works Recommended?
Environment variables import os; pw = os.environ["NET_PASSWORD"] ✔ Yes — simple; keeps credentials out of source code
.env file + python-dotenv Store in a .env file (add to .gitignore); load with from dotenv import load_dotenv ✔ Yes — convenient for development
getpass() import getpass; pw = getpass.getpass() — prompts user at runtime with no echo ✔ Yes — good for interactive scripts
Vault / secrets manager HashiCorp Vault, AWS Secrets Manager, CyberArk — retrieve credentials at runtime via API ✔ Best for production automation pipelines
Hard-coded in script Password written directly as a string literal in the source code ✘ Never — credentials leak into version control

10. Error Handling in Network Scripts

Network devices are unreliable — SSH timeouts, authentication failures, and command errors are normal. Production automation scripts must handle errors gracefully so that one failed device does not crash the entire script.

#!/usr/bin/env python3
"""
Script 8: Robust multi-device script with proper error handling,
logging, and result collection.
"""

from netmiko import ConnectHandler
from netmiko.exceptions import (
    NetMikoTimeoutException,
    NetMikoAuthenticationException,
)
import logging
import json
from datetime import datetime

# Configure logging to file and console
logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s %(levelname)s %(message)s",
    handlers=[
        logging.FileHandler(f"netauto_{datetime.now().strftime('%Y%m%d_%H%M')}.log"),
        logging.StreamHandler()
    ]
)

devices = [
    {"device_type": "cisco_ios", "host": "10.0.0.1",
     "username": "admin", "password": "cisco123", "secret": "enable123"},
    {"device_type": "cisco_ios", "host": "10.0.0.2",
     "username": "admin", "password": "wrongpass", "secret": "enable123"},
    {"device_type": "cisco_ios", "host": "10.0.99.99",   # Unreachable
     "username": "admin", "password": "cisco123", "secret": "enable123"},
]

results = {}

for device in devices:
    host = device["host"]
    logging.info(f"Connecting to {host}")

    try:
        conn = ConnectHandler(**device)
        conn.enable()
        hostname = conn.find_prompt().replace("#", "")
        output   = conn.send_command("show ip interface brief")
        conn.disconnect()

        results[host] = {"status": "success", "hostname": hostname,
                         "output": output}
        logging.info(f"{host} ({hostname}) — SUCCESS")

    except NetMikoTimeoutException:
        results[host] = {"status": "timeout"}
        logging.error(f"{host} — TIMEOUT (device unreachable)")

    except NetMikoAuthenticationException:
        results[host] = {"status": "auth_failed"}
        logging.error(f"{host} — AUTHENTICATION FAILED")

    except Exception as e:
        results[host] = {"status": "error", "message": str(e)}
        logging.error(f"{host} — ERROR: {e}")

# Summary
print(f"\n{'='*50}")
print("SUMMARY")
print(f"{'='*50}")
for host, result in results.items():
    print(f"{host:<15} {result['status']}")

# Save full results to JSON
with open("results.json", "w") as f:
    json.dump(results, f, indent=2)
print("\nResults saved to results.json")

11. Python for Networking Quick-Reference Summary

Concept Key Fact
Primary Python SSH library for network devices Netmiko — built on Paramiko; handles 50+ vendor platforms
Netmiko device type for Cisco IOS "cisco_ios"
Send a show command (Netmiko) conn.send_command("show version")
Send config commands (Netmiko) conn.send_config_set(["cmd1", "cmd2"])
Parse output to structured data (Netmiko) send_command("show …", use_textfsm=True) → list of dicts
NAPALM purpose Vendor-neutral API — same code works on IOS, EOS, JunOS; returns structured dicts
NAPALM get device facts device.get_facts() — hostname, model, vendor, OS version, serial, uptime
NAPALM safe config change workflow load_merge_candidate → compare_config → commit_config (or discard_config)
TextFSM + NTC-Templates purpose Parse raw CLI show-command output to structured Python lists/dicts using pre-built regex templates
Never do this with credentials Hard-code passwords in scripts — use environment variables, .env, getpass(), or a secrets manager
Netmiko install pip install netmiko
NAPALM install pip install napalm
NTC-Templates install pip install ntc_templates
Netmiko exception for unreachable device NetMikoTimeoutException
Netmiko exception for wrong password NetMikoAuthenticationException

Test Your Knowledge – Python for Networking Quiz

1. What is the primary advantage of using Netmiko over raw Paramiko for SSH-based network automation?

Correct answer is C. Paramiko is a low-level SSH library that gives you a raw SSH channel — you have to manually handle every device's unique prompt patterns, --More-- pagination, enable password prompts, and timing. Netmiko is built on Paramiko and abstracts all of this. The device_type parameter selects the correct behaviour profile for that vendor, and Netmiko automatically sends terminal length 0, detects the prompt, enters enable mode if needed, and waits for command completion before returning output.

2. What does the Netmiko method send_config_set(["interface Lo0", "ip address 1.1.1.1 255.255.255.255"]) do automatically?

Correct answer is B. send_config_set() is one of Netmiko's most useful automation-friendly methods. It automatically: (1) enters global configuration mode (configure terminal); (2) sends each command in the provided list sequentially; (3) exits config mode with end after all commands are sent. This means your script just passes a list of configuration commands — you never need to worry about mode management. Note: it does NOT automatically save the config; use save_config() separately for that.

3. What is the key value proposition of NAPALM compared to Netmiko?

Correct answer is D. NAPALM's core value is vendor abstraction. You write device.get_facts() once and get the same structured Python dictionary with hostname, vendor, model, OS version, and serial number — regardless of whether the device is a Cisco IOS router, an Arista switch, or a Juniper router. Only the driver name changes; the business logic remains identical. Netmiko gives you vendor-aware SSH access but returns raw string output that you must parse; NAPALM always returns structured data.

4. What does passing use_textfsm=True to Netmiko's send_command() do?

Correct answer is A. TextFSM is a template engine that uses regular expression-based grammars to parse unstructured CLI text into structured data. The NTC-Templates project provides pre-built TextFSM templates for hundreds of show commands across major vendors. When use_textfsm=True is passed to send_command(), Netmiko automatically identifies the correct template (based on device type and command) and returns a list of dictionaries — e.g., show ip interface brief returns a list where each dict has keys like intf, ipaddr, status, proto.

5. Which NAPALM method allows you to see exactly what changes would be made to a device's configuration before committing them?

Correct answer is C. compare_config() is called after load_merge_candidate() or load_replace_candidate() to preview what will change on the device. It returns a unified diff string showing lines that would be added (+ prefix) and removed (− prefix). This is a critical safety mechanism for change management — always review the diff before calling commit_config(). If the diff looks wrong, call discard_config() to cancel without changing the device.

6. Why should you never hard-code passwords directly in a Python network automation script?

Correct answer is B. Hard-coded credentials are one of the most common security mistakes in automation. When a script with a hard-coded password is committed to a Git repository (even a private one), the password exists forever in the commit history. If the repo becomes public, is accidentally shared, or is compromised, all embedded credentials are exposed. Use os.environ["NET_PASSWORD"], getpass.getpass(), python-dotenv with a .gitignore-listed .env file, or a proper secrets manager for production automation.

7. A Netmiko script connecting to 20 devices throws a NetMikoTimeoutException on 3 of them, crashing the script. What is the correct fix?

Correct answer is D. Production automation scripts must always wrap per-device operations in try/except. The correct pattern is to import NetMikoTimeoutException and NetMikoAuthenticationException from netmiko.exceptions, wrap the connection block in a try/except, log the specific error type for each failed device, store the failure in a results dictionary, and continue the loop. This way, 3 unreachable devices are logged as failures while the other 17 complete successfully — the script does not crash.

8. You write a NAPALM script that calls get_facts() on a Cisco IOS router today. Next year your network is migrated to Arista EOS switches. What code change is needed to the NAPALM script?

Correct answer is A. This demonstrates NAPALM's core value — write once, run anywhere. The NAPALM get_facts() method returns the same dictionary structure with the same keys (hostname, vendor, model, os_version, etc.) regardless of the underlying vendor. Changing from Cisco IOS to Arista EOS only requires changing the driver from napalm.get_network_driver("ios") to napalm.get_network_driver("eos"). All downstream code that processes the dictionary output remains unchanged.

9. What does the following Netmiko code return, and what type is the variable output?
output = conn.send_command("show ip int brief", use_textfsm=True)

Correct answer is C. When use_textfsm=True is set, Netmiko automatically applies the appropriate NTC-Templates TextFSM template for the command and device type. For show ip interface brief on a Cisco IOS device, the template parses each interface line and returns a Python list of dictionaries. Each dictionary represents one interface row with consistent keys: {"intf": "GigabitEthernet0/0", "ipaddr": "192.168.1.1", "status": "up", "proto": "up"}. This structured data can be directly iterated, filtered, and compared in Python without any manual string parsing.

10. A network engineer has a fleet of 200 Cisco IOS routers and needs to collect the running configuration of every device and save it to a file named after each device's hostname. Which approach is most appropriate?

Correct answer is B. This is exactly the use case Python network automation was built for. A Netmiko script iterates a list of 200 device IPs, connects to each, runs send_command("show running-config"), extracts the hostname from the CLI prompt using find_prompt().replace("#", ""), and writes the output to f"{hostname}_running.txt". The entire operation takes a few minutes instead of hours. For even cleaner structured retrieval, NAPALM's get_config(retrieve="running") returns the config in a dictionary. Error handling ensures failed devices are logged without crashing the script.

← Back to Home