Python for Network Engineers — Part 1: Why Python in 2026, Environment Setup, and Your AI Pair Programmer

If you’ve spent any time in network engineering circles recently, you’ll have heard the word automation more times than you’ve heard the word VLAN. Most of that conversation eventually lands on Python. This series is a ground-up guide to understanding why — and to actually using it.

There are other Python-for-networking resources out there. This one is different in two ways: it assumes nothing about your programming background, and it’s written for 2026 rather than 2016. That means a modern toolchain, real-world examples that go beyond “print hello world”, and an honest conversation about where AI tools fit into your workflow — and where they don’t.

By the end of this twelve-part series you’ll be able to connect to network devices over SSH, parse their output, generate configs from templates, hit vendor REST APIs, and run automation jobs in parallel across a fleet. You’ll also have a clear-eyed view of how to use AI tools to write better code faster, without outsourcing your understanding to a chatbot.


Why Python in 2026?

The honest answer is: because the network industry decided it was Python, and that decision has compounded for a decade.

That’s not a cynical answer. When an ecosystem converges on a language, practical things follow. Every major vendor — Cisco, Arista, Juniper, Fortinet, Palo Alto — either ships Python on-box, exposes a Python SDK, or has a mature community library built around it. The tools that network engineers reach for most (Netmiko, NAPALM, Nornir, TextFSM) are all Python. The Ansible modules that talk to network devices are written in Python. If you need help, every forum answer, every GitHub repo, and every AI assistant’s training data skews heavily towards Python for this domain.

There’s a second answer that matters more now than it did five years ago: AI coding assistants work best with Python. Tools like Claude, GitHub Copilot, and ChatGPT have seen more Python network automation code in their training data than any other language. When you ask an AI to write a Netmiko script or explain a Nornir error, you get a better answer than you would for equivalent code in Go or Bash. That’s a practical advantage worth acknowledging.

What Python is not is the only tool. Shell scripts still belong in your kit. Ansible still makes sense for configuration management at scale. Terraform owns infrastructure-as-code. Python fits in the layer that ties those things together and handles the logic that can’t be expressed in a declarative format — reading device state, making decisions, producing structured output, calling APIs.


Setting Up Your Environment

Before writing a single line of Python, get your environment right. The choices you make here follow you through everything else in this series.

Install Python

Download Python 3.12 or later from python.org. On Windows, use the installer and check “Add Python to PATH” during setup. On macOS, use the installer rather than the system Python (the one that ships with macOS is old and managed by the OS). On Linux, your distribution’s package manager will have a recent version — apt install python3 on Debian/Ubuntu, dnf install python3 on RHEL/Fedora.

Confirm it works:

python3 --version
# Python 3.12.x

On Windows you may need python rather than python3. Throughout this series, all examples use python3.

Install uv

uv is a modern Python package manager that replaces both pip and venv. It’s significantly faster and handles virtual environments cleanly. Think of it as the tool that should have existed from the start.

# macOS / Linux
curl -LsSf https://astral.sh/uv/install.sh | sh

# Windows (PowerShell)
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"

Confirm installation:

uv --version

Every project in this series will use a uv-managed virtual environment. The pattern is always the same:

# Create a new project folder
mkdir network-automation
cd network-automation

# Initialise a virtual environment
uv venv

# Activate it
source .venv/bin/activate        # macOS / Linux
.venv\Scripts\activate           # Windows PowerShell

# Install a package
uv pip install netmiko

# When you're done
deactivate

The virtual environment keeps your project’s dependencies isolated from everything else on your system. This matters in network automation because different projects often need different versions of the same library. Get into the habit of creating one per project, always.

Install VS Code

Visual Studio Code is the editor this series uses. It’s free, it runs everywhere, and its Python support is best-in-class — syntax highlighting, inline error detection, integrated terminal, and the GitHub Copilot extension all work well together.

Download it from code.visualstudio.com. Once installed, open VS Code and install the Python extension:

  • Open the Extensions panel (Ctrl+Shift+X / Cmd+Shift+X)
  • Search for “Python” by Microsoft
  • Install it

When you open a Python file, VS Code will detect your virtual environment automatically if it’s in a .venv folder inside the project. You’ll see the interpreter shown in the status bar at the bottom. Click it to switch if it picks the wrong one.

Set Up Git

Git is how you track changes to your scripts, share them with others, and avoid the chaos of config_final_v3_ACTUAL_FINAL.py. Install it from git-scm.com if it’s not already on your system:

git --version

Configure your identity — this gets attached to every commit you make:

git config --global user.name "Your Name"
git config --global user.email "[email protected]"

For every project in this series, initialise a repository on day one:

git init

Create a .gitignore file to keep noise out of your history:

.venv/
__pycache__/
*.pyc
.env

That last line is important: never commit files containing credentials or API tokens. Throughout this series, any sensitive value (passwords, API keys, device credentials) lives in environment variables or a .env file that stays off Git.

The minimum Git workflow to know right now:

git add filename.py        # Stage a file
git add .                  # Stage everything
git commit -m "Add subnet calculator script"   # Save a snapshot
git log --oneline          # See history

You don’t need to understand branches or pull requests yet. Commit often, use a meaningful message, and you’ll have a recoverable history from day one.


Your AI Pair Programmer

This section might be the most practically useful thing in this first post.

AI coding assistants — Claude, GitHub Copilot, ChatGPT — have changed what it means to learn programming. Not by removing the need to learn it, but by changing the feedback loop. When you were stuck before, you searched Stack Overflow, read documentation, and waited. Now you can describe your problem in plain English and get a working starting point in seconds.

That’s genuinely valuable. But for network engineers, there’s a discipline that has to come with it: you must understand every line of code before you run it against a device. An AI-generated script that looks plausible but has a logic error could misconfigure production equipment. “The AI wrote it” is not a defence.

The right mental model is pair programmer, not ghostwriter. You are the senior engineer in the room. The AI drafts, you review, you understand, you run.

What AI is Good At

Explaining concepts. If anything in this series is unclear, paste it into Claude or ChatGPT and ask it to explain it differently. “Explain Python dictionaries as if I’m a network engineer who understands VRFs” is a better prompt than “explain Python dictionaries.”

Writing first drafts. Describe what you want in plain English, with context. Don’t just say “write a Netmiko script” — say “write a Python script using Netmiko that connects to a Cisco IOS-XE router over SSH, runs show ip interface brief, and prints the output. The device IP is stored in a variable, and credentials come from environment variables.” More context produces more useful code.

Debugging. Paste your code and the error message. Ask “what’s wrong with this code and why?” This is often faster than reading a stack trace yourself, especially while you’re still learning.

Translating vendor syntax. “What’s the Fortinet FortiOS equivalent of the Cisco ip inspect command?” AI is good at cross-vendor translation questions that would otherwise require two browser tabs and a lot of squinting.

What AI Gets Wrong

AI confidently produces code that doesn’t work, references library functions that don’t exist, and sometimes generates network configurations that are syntactically valid but operationally wrong. In network automation specifically, watch out for:

  • Deprecated function signatures. Netmiko, NAPALM, and Nornir evolve. AI may use an older API.
  • Hardcoded credentials. AI often puts passwords directly in code by default. Always move them to environment variables.
  • Missing error handling. AI-generated scripts often assume everything works. Network devices are not reliable; your code needs to handle SSH timeouts, auth failures, and unexpected output.
  • Wrong platform assumptions. “Cisco” is not specific enough. IOS, IOS-XE, IOS-XR, NX-OS, and ASA all behave differently in Netmiko.

Run AI-generated code in a lab first, every time. Read it before you run it. If you don’t understand a line, ask the AI to explain it. That explanation is how you learn.

Suggested Setup

GitHub Copilot works inside VS Code and provides inline completions as you type. It’s subscription-based (~$10/month) and the most frictionless option if you want suggestions while coding.

Claude (at claude.ai) is better for longer context — pasting a full configuration file for review, analysing a 200-line script, or asking detailed architecture questions. It handles larger inputs more gracefully.

Both are useful. Copilot for micro-level suggestions; Claude for macro-level questions and review. This series was written using both.


Your First Script

Environment is up. AI tools are ready. Let’s write something useful.

For a first script, “hello world” is a waste of your time. Instead: a script that reads a plain-text file of device names and IP addresses, validates each IP, and prints a formatted summary. It’s the kind of thing you’d build as a sanity check before running automation against a device list.

Create a new folder, initialise a venv, and create two files:

mkdir first-script
cd first-script
uv venv
source .venv/bin/activate    # or .venv\Scripts\activate on Windows
git init

Create devices.txt — a plain list of devices you want to manage:

core-sw-01,192.168.1.1
core-sw-02,192.168.1.2
edge-rtr-01,10.0.0.1
broken-entry,not-an-ip
spine-01,172.16.0.1

The last entry is deliberately broken. A useful script handles bad data gracefully.

Now create inventory.py:

import ipaddress

DEVICE_FILE = "devices.txt"


def parse_device_line(line):
    """Parse a single 'hostname,ip' line. Returns (hostname, ip) or raises ValueError."""
    parts = line.strip().split(",")
    if len(parts) != 2:
        raise ValueError(f"Expected 'hostname,ip' format, got: {line.strip()!r}")
    hostname, ip_str = parts[0].strip(), parts[1].strip()
    ip = ipaddress.ip_address(ip_str)   # raises ValueError if invalid
    return hostname, ip


def load_inventory(filepath):
    """Read a device file and return a list of (hostname, ip) tuples.
    
    Lines that fail to parse are reported but don't stop the script.
    """
    valid = []
    errors = []

    with open(filepath) as f:
        for line_number, line in enumerate(f, start=1):
            line = line.strip()
            if not line or line.startswith("#"):   # skip blanks and comments
                continue
            try:
                hostname, ip = parse_device_line(line)
                valid.append((hostname, ip))
            except ValueError as e:
                errors.append((line_number, str(e)))

    return valid, errors


def main():
    devices, errors = load_inventory(DEVICE_FILE)

    print(f"\n{'Hostname':<20} {'IP Address':<18} {'Version'}")
    print("-" * 50)
    for hostname, ip in devices:
        version = "IPv4" if ip.version == 4 else "IPv6"
        print(f"{hostname:<20} {str(ip):<18} {version}")

    if errors:
        print(f"\n{len(errors)} line(s) could not be parsed:")
        for line_number, message in errors:
            print(f"  Line {line_number}: {message}")

    print(f"\nTotal valid devices: {len(devices)}")


if __name__ == "__main__":
    main()

Run it:

python3 inventory.py

Expected output:

Hostname             IP Address         Version
--------------------------------------------------
core-sw-01           192.168.1.1        IPv4
core-sw-02           192.168.1.2        IPv4
edge-rtr-01          10.0.0.1           IPv4
spine-01             172.16.0.1         IPv4

1 line(s) could not be parsed:
  Line 4: 'not-an-ip' does not appear to be an IPv4 or IPv6 address

Total valid devices: 4

This script uses nothing outside the Python standard library — no pip installs. It also introduces concepts that appear throughout this series: reading files, string manipulation, exception handling, functions, and if __name__ == "__main__". We’ll come back to each of those in detail in the next three posts.

Commit what you have:

git add .
git commit -m "Add inventory parser script"

What’s Coming in Part 2

Part 2 covers Python’s core data types in depth — strings, numbers, booleans, files, lists, and tuples — with examples drawn from real network engineering scenarios. IP addresses, config file parsing, device output manipulation. By the end of it, the inventory script above will make complete sense, and you’ll be writing variations of it from scratch.

The series covers twelve posts in total, building from fundamentals to a full multi-device automation framework. You can see the complete roadmap at /guides/python/network-engineers/.


No Containerlab topology is needed for this post — all examples run without network devices. Topologies appear from Part 5 onwards when we start connecting to devices.