Lesson 3 of 5

Python Basics for Networking

Lab Objectives

  • Learn basic Python data types used for network automation: variables, lists, dictionaries, and loops.
  • Build a simple Netmiko script that connects to a list of routers and runs show ip interface brief.
  • Understand why lists/dictionaries and loops are useful when automating repetitive network tasks in production.

Lab Tasks (Try It Yourself First!)

Complete these tasks WITHOUT looking at the solution below. Use ? and show commands to figure it out.

Task 1: Create devices.txt

Create a text file named devices.txt that contains the management IP addresses (one per line) used to reach R1–R4. Use these exact IP addresses:

  • 172.25.1.1
  • 172.25.1.2
  • 172.25.1.3
  • 172.25.1.4

Use username khawar and password Lab@123 in your script.

Task 2: Simple Netmiko Script (file read)

Write a Python script called Lab9.py that:

  • Reads devices.txt line-by-line.
  • For each IP, uses ConnectHandler from the netmiko library to connect to the device (device_type cisco_ios).
  • Runs the command show ip interface brief and prints the output to the console.

Task 3: Use a list of dictionaries and a loop

Re-write the script so device connection parameters are stored as a list of dictionaries (one dictionary per device). Loop over that list and run show ip interface brief on each device. Ensure the script cleanly disconnects from each device.

Think About It: Why is a list of dictionaries a better structure for managing many devices than repeatedly opening and reading a flat file? Consider maintainability and adding attributes later (e.g., port, vendor, role).


Lab Solution

Topology (use this exact ASCII diagram in your lab environment):

                [Internet]
               203.0.113.1
                    |
               R1 (Gateway)
              Gi0/0: 10.10.10.1
              Gi0/1: 10.10.20.1
              Gi0/2: 10.10.30.1
              /     |     \
           R2      R3      R4

Gi0/0: 10.10.10.2 | Gi0/0: 10.10.30.2 Gi0/1: 10.10.40.1 | / \ | S1 S2 S3 / \ | /
PC1 PC2 PC3 PC4 PC5

IP SCHEME (for reference):

  • 10.10.10.0/24 — R1-R2 link
  • 10.10.20.0/24 — R1-R3 link
  • 10.10.30.0/24 — R1-R4 link
  • 10.10.40.0/24 — R2-S1 link
  • 192.168.1.0/24 — VLAN 10 (Sales)
  • 192.168.2.0/24 — VLAN 20 (Engineering)
  • 192.168.3.0/24 — VLAN 30 (Management)
  • 203.0.113.0/24 — Public/Internet simulation

Task 1 Solution: Create devices.txt

What we are doing: Create a simple text file with one IP per line. This is the most portable way to maintain a list of devices; automation scripts can read it line-by-line.

Commands to create and view file:

echo "172.25.1.1" > devices.txt
echo "172.25.1.2" >> devices.txt
echo "172.25.1.3" >> devices.txt
echo "172.25.1.4" >> devices.txt

# View the file
cat devices.txt

What the commands do and why they matter:

  • echo "IP" > devices.txt creates the file and writes the first IP. >> appends subsequent IPs.
  • Keeping the list in a plain text file makes it easy to add/remove devices without editing the script — a common operational practice.

Verify:

cat devices.txt

Expected output:

172.25.1.1
172.25.1.2
172.25.1.3
172.25.1.4

Tip: Leading/trailing spaces or blank lines in devices.txt can cause malformed IP strings when read by Python. Keep the file clean.

Task 2 Solution: Simple Netmiko Script (file read)

What we are doing: Use Netmiko's ConnectHandler to connect to each device IP from the file and run show ip interface brief. This demonstrates variables, file iteration, and calling network commands from Python.

Create Lab9.py with the following contents:

# Lab9.py
from netmiko import ConnectHandler

username = 'khawar'
password = 'Lab@123'

with open('devices.txt') as routers:
    for ip in routers:
        ip = ip.strip()               # remove newline/spaces
        device = {
            'device_type': 'cisco_ios',
            'ip': ip,
            'username': username,
            'password': password
        }

        print('Connecting to ' + ip)
        net_connect = ConnectHandler(**device)

        output = net_connect.send_command('show ip interface brief')
        print('-' * 80)
        print(output)
        print('-' * 80)

        net_connect.disconnect()

What just happened (line-by-line):

  • username / password — simple variables storing credentials.
  • with open('devices.txt') as routers: — opens the file and iterates over lines.
  • ip = ip.strip() — removes newline characters; prevents malformed IP strings.
  • device = { ... } — a dictionary holding connection parameters; dictionaries map keys to values (like a phonebook: "host" -> "10.0.0.1").
  • ConnectHandler(**device) — unpacks the dictionary into keyword arguments for Netmiko.
  • send_command('show ip interface brief') — runs the IOS command and returns output.
  • net_connect.disconnect() — cleanly closes the SSH session.

Why this matters: Using a dictionary for device parameters lets you add fields later (e.g., port, secret, device_role) without refactoring the connection logic. Looping over devices automates repetitive tasks that would be error-prone if done manually.

Verify: Run:

python3 Lab9.py

Expected console excerpt (example output for R1 — show ip interface brief):

Interface              IP-Address      OK? Method Status                Protocol
GigabitEthernet0/0     10.10.10.1      YES manual up                    up
GigabitEthernet0/1     10.10.20.1      YES manual up                    up
GigabitEthernet0/2     10.10.30.1      YES manual up                    up
Loopback0              172.25.1.1      YES manual up                    up

Real-world note: In production, scripts like this are run from a secured automation host with SSH keys or vaults for credentials. This simple example uses basic auth for learning.

Task 3 Solution: Use a list of dictionaries and a loop

What we are doing: Store each device as a dictionary in a list. Iterate that list to connect. This demonstrates lists + dictionaries + loops — essential building blocks for automation.

Example Lab9_list.py:

from netmiko import ConnectHandler

devices = [
    {'device_type': 'cisco_ios', 'ip': '172.25.1.1', 'username': 'khawar', 'password': 'Lab@123'},
    {'device_type': 'cisco_ios', 'ip': '172.25.1.2', 'username': 'khawar', 'password': 'Lab@123'},
    {'device_type': 'cisco_ios', 'ip': '172.25.1.3', 'username': 'khawar', 'password': 'Lab@123'},
    {'device_type': 'cisco_ios', 'ip': '172.25.1.4', 'username': 'khawar', 'password': 'Lab@123'}
]

for dev in devices:
    print('Connecting to ' + dev['ip'])
    net_connect = ConnectHandler(**dev)
    output = net_connect.send_command('show ip interface brief')
    print('-' * 80)
    print(output)
    print('-' * 80)
    net_connect.disconnect()

What just happened:

  • devices is a list containing dictionary entries. Think of the list as a stack of device cards; each card (dictionary) holds labeled fields.
  • The for dev in devices: loop iterates each device card and performs the same actions — this is the core of automation: define once, repeat many times reliably.

Verify:

python3 Lab9_list.py

You should see Connecting to 172.25.1.x followed by each device’s show ip interface brief output.


Troubleshooting Scenario

Scenario: devices.txt contains malformed IP entries

Symptom: The script aborts with a connection error or Netmiko raises an exception for an invalid host. Example line in devices.txt: 172.25.1. 3 (extra space before the digit).

Your task: Find and fix the issue.

Hint: Check for stray spaces or blank lines in devices.txt and ensure your script strips whitespace.

Solution:

  • Edit devices.txt and remove any extra spaces so each line is exactly 172.25.1.3.
  • Ensure the script uses ip.strip() when reading lines (as shown in Task 2).
  • Re-run python3 Lab9.py — script should now connect.

Warning: Leaving trailing spaces is a common source of failures when reading file-based device inventories.

Verification Checklist

  • devices.txt exists and lists four IPs (172.25.1.1–172.25.1.4).
  • Lab9.py runs without syntax errors.
  • Script prints show ip interface brief for each device and disconnects cleanly.

Common Mistakes

SymptomCauseFix
Script throws connection or address errorBlank lines or trailing spaces in devices.txtRemove blank lines; use ip.strip() in script
Authentication failureWrong password or usernameVerify credentials; update password = 'Lab@123' if needed
Script leaves hanging SSH sessionsForgot disconnect()Add net_connect.disconnect() after commands
Hard-coded single deviceNot using lists/dictsUse a list of dictionaries to scale to many devices

Challenge Task

Modify the list-based script so that for each device the script runs two commands (show ip interface brief and show running-config | include hostname) and writes each device’s output to a separate file named <ip>_show_ip_int_brief.txt. Do this without using any third-party libraries beyond Netmiko.

This exercise forces you to combine loops, I/O, and string/file handling — the same operations used in real automation workflows.

Key takeaway: variables hold single values, lists hold ordered collections, dictionaries map keys to values; loops let you apply the same operation across many devices. In production networks, these patterns scale manual tasks into repeatable automation, reducing human error and saving time.