14.1 Python Fundamentals for Network Engineers: Data Types, Control Flow, and Libraries

Key Takeaways

  • Python serves as the core programming environment in network automation, replacing brittle screen-scraping CLI scripts with programmatic, structured API and model-driven interactions.

  • Primitive data types include strings (str, supporting slicing and f-string interpolation), integers (int), floating-point numbers (float), and booleans (bool) for conditional flags.

  • Collection data types structure device information: ordered mutable lists (list), immutable tuples (tuple), key-value dictionaries (dict) for configuration trees and API payloads, and unique sets (set) for membership and difference checks.

  • Control flow mechanisms—including if/elif/else conditionals, for loops over device inventories, polling while loops, and list comprehensions—orchestrate dynamic workflow execution.

  • The requests library manages HTTP REST API transactions (GET, POST, headers, basic/token auth, JSON parsing), while ncclient establishes SSH-based NETCONF sessions to exchange XML RPCs such as get-config and edit-config.

Last updated: October 2026

Python Fundamentals for Network Engineers: Data Types, Control Flow, and Libraries

Enterprise network engineering has transitioned from manual command-line interface (CLI) interactions to programmatic infrastructure automation. Managing hundreds of routers, switches, and wireless access points individually through terminal emulators is slow, prone to human error, and incompatible with modern continuous integration and continuous deployment (CI/CD) pipelines. Python has emerged as the primary programming language for network automation due to its clear readability, extensive standard library, and broad ecosystem of specialized networking packages. Network engineers leverage Python to interact with RESTful APIs on software-defined controllers, dispatch model-driven Remote Procedure Calls (RPCs) over NETCONF, parse structured telemetry, and validate configuration state across complex campus and WAN environments.

+-------------------------------------------------------------------------+
|                    Network Automation Execution Stack                   |
+-------------------------------------------------------------------------+
|  Application Layer: Custom Python Scripts, Workflows, Audit Logic       |
+-------------------------------------------------------------------------+
                                     |
        +----------------------------+----------------------------+
        v                                                         v
+--------------------------------+       +--------------------------------+
|      REST Automation Stack     |       |    NETCONF Automation Stack    |
|  Library: 'requests'           |       |  Library: 'ncclient'           |
|  Payload: JSON Data / RESTCONF |       |  Payload: YANG-modeled XML     |
|  Transport: HTTPS (TCP 443)    |       |  Transport: SSH Subsystem (830)|
+--------------------------------+       +--------------------------------+
        |                                                         |
        +----------------------------+----------------------------+
                                     v
+-------------------------------------------------------------------------+
| Enterprise Infrastructure: Catalyst Switches, Routers, SD-WAN, ISE     |
+-------------------------------------------------------------------------+

Primitive Data Types in Network Automation

Python provides several built-in primitive data types that represent fundamental network values such as IP addresses, port identifiers, operational statuses, and interface metrics:

Strings (str)

Strings are immutable sequences of Unicode characters used extensively to store hostnames, interface names, IP addresses, configuration snippets, and raw CLI outputs. Because strings are immutable, operations that manipulate them produce new string objects rather than modifying the original in place.

  • Slicing: Python strings support slicing syntax string[start:stop:step] to extract specific substrings. For example, given an interface identifier intf = "GigabitEthernet0/1", slicing intf[0:2] yields "Gi" for shorthand naming, while intf[-3:] yields "0/1".
  • String Methods: Methods such as .split(), .strip(), and .replace() help parse text. Calling "192.168.10.1/24".split("/") separates an IP prefix into the host address "192.168.10.1" and prefix length "24".
  • Formatted String Literals (f-strings): Introduced in Python 3.6, f-strings provide an efficient, readable syntax for embedding variables and expressions directly inside string literals by prefixing the string with f or F and placing expressions inside curly braces {}:
hostname = "core-rtr-01"
vlan_id = 100
vlan_name = "USERS"
config_cmd = f"vlan {vlan_id}\n name {vlan_name}\n! Configured on {hostname}"

Integers (int) and Floating-Point Numbers (float)

Integers represent whole numbers of arbitrary precision and are used for Autonomous System (AS) numbers, VLAN IDs (1–4094), Access Control List (ACL) numbers, interface bandwidth values, and TCP/UDP port numbers. Floats represent decimal values, commonly encountered when monitoring interface utilization percentages (e.g., 87.4%), link error rates, or CPU load averages.

Booleans (bool)

Booleans evaluate to either True or False. In network programming, booleans serve as flags indicating operational conditions—such as whether an interface is administratively enabled (is_up = True), whether an authentication token has expired, or whether an API response was successful.

Collection Data Types for Network State

Automating network tasks requires grouping individual primitives into structured collections. Python offers four primary collection types, each with distinct mutability, ordering, and indexing characteristics:

Collection Data Types Overview:
[ List: ["Gi0/1", "Gi0/2"] ]  --> Ordered, mutable sequence; indexed by integer
[ Tuple: ("10.1.1.1", 22) ]   --> Ordered, immutable sequence; protected record
[ Dict: {"vlan": 10, ...} ]   --> Key-value mapping; models structured device state
[ Set: {"10.1.1.1", ...} ]    --> Unordered unique values; membership & diffs

Lists (list)

Lists are ordered, mutable sequences enclosed in square brackets []. Elements are zero-indexed and can be modified, appended, or removed dynamically:

  • Elements are accessed via their index: devices[0] retrieves the first element, while devices[-1] retrieves the last.
  • Appending elements: devices.append("10.1.1.5") adds an address to the end.
  • Removing elements: devices.pop() removes and returns the trailing item, while .remove(value) deletes the first occurrence of a specific value.
  • Common use case: Maintaining an ordered sequence of management IP addresses to iterate across during backup jobs.

Tuples (tuple)

Tuples are ordered, immutable sequences defined using parentheses (). Once created, items cannot be added, replaced, or removed. Tuples provide data integrity for fixed constants that should never change during script execution, such as socket address pairs (ip_address, port) or coordinate pairs.

Dictionaries (dict)

Dictionaries are mutable mappings composed of key-value pairs wrapped in curly braces {}. Keys must be unique and immutable (typically strings), while values can be any Python object, including other dictionaries and lists. Dictionaries represent the core data structure for modeling network configurations, device attributes, and JSON-based API responses:

  • Accessing values: Bracket notation device["ip"] retrieves the value but raises a KeyError if the key is missing. Using the safer .get(key, default) method returns None (or a specified fallback) if the key does not exist.
  • Iteration: The .keys() method returns all keys, .values() returns all values, and .items() returns key-value tuples for simultaneous iteration.
  • Nested Dictionaries: Deep structures mirror network hierarchies, such as a device containing an interfaces dictionary where each interface key maps to properties like IP, subnet mask, and administrative state.

Sets (set)

Sets are unordered collections of unique elements enclosed in curly braces {} (or initialized with set()). Sets automatically deduplicate input values and support mathematical set operations:

  • Union (|): Combines elements from both sets.
  • Intersection (&): Identifies elements present in both sets.
  • Difference (-): Identifies elements present in the first set but absent in the second.
  • Common use case: Comparing configured VLANs across two distribution switches to detect VLAN trunk mismatches.

Python Data Types Comparison Matrix

Data TypeMutabilitySyntax / DelimiterKey CharacteristicsNetwork Automation Use Case
String (str)ImmutableQuotes: '...' or "..."Sequence of Unicode characters; slicing and f-stringsCLI commands, banner generation, IP string storage
Integer (int)ImmutableNumeric literal: 42Arbitrary precision whole numbersVLAN IDs, BGP ASNs, TCP/UDP ports, MTU settings
Float (float)ImmutableDecimal literal: 3.14Double-precision floating-point numbersInterface load %, telemetry metrics, latency values
Boolean (bool)ImmutableLiterals: True or FalseLogical truth values; subclass of integerOperational flags, interface state, error checks
List (list)MutableSquare brackets: [...]Ordered sequence; permits duplicates; zero-indexedDevice inventory lists, interface queues, IP pools
Tuple (tuple)ImmutableParentheses: (...)Ordered sequence; cannot be modified once setSocket endpoints (host, port), fixed database records
Dictionary (dict)MutableCurly braces: {key: val}Associative key-value mapping; keys must be uniqueParsed JSON payloads, device configs, YANG mappings
Set (set)MutableCurly braces: {val1, val2}Unordered collection of unique items; set algebraVLAN mismatch detection, deduping discovered endpoints

Control Flow and Iteration Patterns

Control flow statements govern script execution based on runtime conditions, network state, and API response values.

Conditional Logic (if, elif, else)

Conditional statements evaluate boolean expressions using comparison operators (==, !=, <, >, <=, >=) and logical operators (and, or, not, in):

interface_status = "down"
admin_enabled = True

if interface_status == "up":
    print("Interface operational")
elif interface_status == "down" and admin_enabled:
    print("Alert: Interface administratively up but operationally down!")
else:
    print("Interface administratively shut down")

Iteration with for and while Loops

for loops iterate over iterable objects such as lists, dictionaries, or IP networks generated by the ipaddress module:

devices = [
    {"hostname": "dist-sw01", "ip": "10.1.1.1", "platform": "iosxe"},
    {"hostname": "dist-sw02", "ip": "10.1.1.2", "platform": "iosxe"}
]

for dev in devices:
    print(f"Connecting to {dev['hostname']} at {dev['ip']}...")

while loops repeat a block of code as long as a condition evaluates to True. They are frequently used when polling asynchronous jobs on controllers—such as checking whether a configuration push task has finished—typically bounded by a retry counter or timeout to prevent infinite execution.

List Comprehensions

List comprehensions provide a concise, readable syntax for generating new lists from existing iterables by applying expressions and optional filters:

# Extract reachable management IPs from a list of device dictionaries
reachable_ips = [dev["ip"] for dev in devices if dev.get("reachable", False)]

Modular Code Architecture: Functions

Functions allow engineers to organize procedural code into reusable, testable blocks. Defined using the def keyword, functions accept input arguments (positional or keyword) and return computed results via the return statement:

def build_interface_config(intf_name, vlan_id, mode="access"):
    """Generates standard Cisco IOS XE switchport configuration."""
    commands = [
        f"interface {intf_name}",
        f"switchport mode {mode}"
    ]
    if mode == "access":
        commands.append(f"switchport access vlan {vlan_id}")
    elif mode == "trunk":
        commands.append(f"switchport trunk allowed vlan add {vlan_id}")
    return "\n".join(commands)

Essential Network Automation Libraries: requests vs. ncclient

While Python's standard library provides raw socket and HTTP tools, enterprise network automation relies on specialized third-party libraries designed for networking workflows.

The requests Library for RESTful APIs

The requests library simplifies HTTP communication with controller platforms such as Cisco Catalyst Center, Cisco Catalyst SD-WAN Manager, and RESTCONF-enabled switches:

  • HTTP Methods: Corresponds directly to REST API operations: requests.get() to retrieve resources, requests.post() to create resources, requests.put() to replace resources, requests.patch() for partial updates, and requests.delete() to remove resources.
  • Authentication: Supports basic authentication via auth=("admin", "password") or custom token-based headers (headers={"X-Auth-Token": token}).
  • Response Handling: Returns a Response object containing the HTTP status code (.status_code), raw response text (.text), and automated JSON decoding (.json()).
import requests
from requests.auth import HTTPBasicAuth

url = "https://10.1.1.1/restconf/data/ietf-interfaces:interfaces"
headers = {
    "Accept": "application/yang-data+json",
    "Content-Type": "application/yang-data+json"
}

response = requests.get(
    url,
    headers=headers,
    auth=HTTPBasicAuth("cisco", "cisco123!"),
    verify=False,  # Bypasses self-signed certificate check in lab
    timeout=10
)

if response.status_code == 200:
    data = response.json()
    print("Successfully retrieved interface configuration")
else:
    print(f"Request failed with status: {response.status_code}")

The ncclient Library for NETCONF Operations

The ncclient library is a Python client library for NETCONF (RFC 6241 and RFC 6242), establishing SSH transport connections on TCP port 830 to exchange XML-encoded RPCs:

  • Connection Management: Initiated using manager.connect(), specifying parameters such as host, port=830, username, password, hostkey_verify=False, and device_params={"name": "iosxe"} to negotiate device-specific capabilities.
  • RPC Operations: Supports standard NETCONF operations, including <get-config> to pull configuration from datastores (such as running or candidate), <edit-config> to modify target configurations, <commit> to apply candidate configurations on platforms supporting two-phase commits, and <get> to retrieve operational state.
  • XML Subtree and XPath Filtering: Employs XML subtree filters or XPath expressions to constrain queries so the device returns only requested subtrees rather than the entire configuration database.
from ncclient import manager

netconf_filter = """
<filter>
  <interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces">
    <interface>
      <name>GigabitEthernet1</name>
    </interface>
  </interfaces>
</filter>
"""

with manager.connect(
    host="10.1.1.1",
    port=830,
    username="admin",
    password="cisco123!",
    hostkey_verify=False,
    device_params={"name": "iosxe"}
) as m:
    reply = m.get_config(source="running", filter=("subtree", netconf_filter))
    print(reply.xml)

Automation Library Comparison: requests vs. ncclient

Dimensionrequests Libraryncclient Library
Underlying ProtocolHTTP / HTTPS (REST and RESTCONF)NETCONF over SSH (RFC 6242)
Default Transport PortTCP 443 (HTTPS) or TCP 80 (HTTP)TCP Port 830 (standard NETCONF)
Data SerializationTypically JSON (also supports XML / plain text)Strictly XML conforming to YANG schemas
Session PersistenceStateless per request (unless requests.Session used)Stateful SSH connection context with capability exchange
Primary OperationsGET, POST, PUT, PATCH, DELETE<get>, <get-config>, <edit-config>, <commit>, <lock>
Target PlatformsCatalyst Center, SD-WAN Manager, RESTCONF devicesCisco IOS XE, IOS XR, and NX-OS NETCONF subsystems
Transaction SupportDepends on REST API endpoint logicNative datastore locking (<lock>) and candidate rollback
Test Your Knowledge

A network engineer needs to safely retrieve an optional BGP neighbor description from a parsed JSON API response dictionary named 'neighbor_data'. If the key 'description' is absent, the script should return 'No Description Provided' without raising an uncaught exception. Which Python expression achieves this?

A

neighbor_data['description']

B

neighbor_data.pop('description', 'No Description Provided')

C

neighbor_data.get('description', 'No Description Provided')

D

neighbor_data['description'] if 'description' not in neighbor_data else None

Test Your Knowledge

When developing a Python script utilizing ncclient to retrieve interface configurations from a Cisco IOS XE router, which parameters and methods are used to establish the transport connection and query the running configuration datastore?

A

manager.connect() over TCP port 830 specifying the device_params, followed by m.get_config(source='running')

B

requests.get() over TCP port 443 with an Accept header for application/xml

C

manager.connect() over TCP port 22 using raw Telnet emulation, followed by m.edit_config(target='running')

D

socket.create_connection() to port 80, followed by m.dispatch('show running-config')

Test Your Knowledge

A network automation script executes requests.post() to create an administrative user on a controller. The HTTP response object has a status_code of 201. How should the script interpret this result?

A

The request was rejected due to invalid authentication credentials

B

The request was accepted and queued for background processing, but the resource is not yet created

C

The server encountered an internal database error during provisioning

D

The resource was successfully created on the server

Sections you finish are checked off in the contents.