Your First Network Automation
Building the Inventory Layer
What you'll learn
- How to load the project's device inventory from a CSV file
- Why inventory should be validated before anything downstream uses it
- How to write a small validation function and use it to filter a device list
- That inventory only holds static facts about a device — not its current state
- How this stage fits into the overall project, before any connection is attempted
Listen to a guided explanation of this lesson.
Spoken narration isn't supported in this browser.
The first real stage
Every stage in this project's plan needs the device list before it can do anything — so that's where the actual building starts. This lesson is entirely about getting a trustworthy inventory into the script; nothing here connects to a device, real or simulated. That's deliberate: get the input right first, and every later stage can just trust it.
Loading the inventory
The project's inventory is a CSV file — exactly the shape from "Reading and Writing CSV Inventory Files":
hostname,ip,platform
SW1,10.10.10.1,cisco_ios
SW2,10.10.10.2,cisco_ios
SW3,10.10.10.3,cisco_iosHostname, management IP, and platform — the static facts about each device, and nothing about its current state. That distinction matters, and this lesson comes back to it.
import csv
with open("devices.csv") as f:
devices = list(csv.DictReader(f))
for device in devices:
print(device["hostname"], device["ip"], device["platform"])csv.DictReader turns the file into a list of dictionaries in one line — exactly the pattern from the Networking Data & Formats module, now the actual starting point of a real project.
Why validate before using it
A CSV file is just text — nothing stops a row from being incomplete (a blank IP, a missing hostname from a copy-paste mistake) before it ever reaches the rest of the script. Left unchecked, a bad record doesn't fail loudly and immediately; it fails somewhere later, in a way that's much harder to trace back to "the inventory had a typo in row 2."
This is the source-of-truth idea, in code
"Devices, Inventory & Source of Truth" argued that automation is only as reliable as the inventory it trusts. Validating a device record before using it is that idea, made concrete: catch a bad record here, with a clear message, instead of letting it cause a confusing failure three stages downstream.
def is_valid_device(device):
"""A device record needs at least a hostname and an IP to be usable."""
return bool(device.get("hostname")) and bool(device.get("ip"))device.get("hostname") returns an empty string if the field is blank; bool("") is False, bool("SW1") is True — so this function returns True only when both fields actually have something in them.
Filtering the list
With the check written, the next step is using it to separate good records from bad ones — a plain loop, exactly like every other filtering step this curriculum has used:
valid_devices = []
for device in devices:
if is_valid_device(device):
valid_devices.append(device)
else:
print(f"Skipping invalid inventory record: {device}")Every device is checked once. A valid one gets added to valid_devices; an invalid one gets a clear, immediate message instead of silently being included — or silently being dropped without anyone noticing.
Inventory vs. state, one more time
Notice what devices.csv does not contain: no reachability, no NTP status, no VLAN information. That's not an oversight — inventory is the static facts about a device (who it is, where it is), while reachability and compliance are state: facts that can only be discovered by actually checking, right now. "Configuration vs State" made exactly this distinction two modules ago; this project keeps it just as clean in real code, and the next lesson is entirely about the stage that discovers state.
Key takeaways
- The inventory layer loads devices.csv into the same list-of-dictionaries shape used throughout this curriculum, using csv.DictReader.
- A device record should be validated before anything downstream uses it — catching a bad record here means a clear message now, not a confusing failure later.
- is_valid_device(device) combined with a plain filtering loop separates usable records from broken ones, without silently dropping or silently accepting either.
- Inventory holds static facts (hostname, IP, platform); reachability and compliance are state, discovered by connecting — which is exactly what the next lesson builds.
- Getting this stage right first means every later stage in the project can simply trust the device list it's handed.