Libraries, pip, and Virtual Environments

You've hand-rolled subnet math, counters, and parsers for eight lessons - on purpose, because now you can appreciate what the standard library and PyPI hand you for free. This lesson is about standing on shoulders: finding, installing, and trusting other people's code.

TL;DR - only got 10 minutes? This is the lesson. Hit to have it read to you.
  • Python ships "batteries included": import ipaddress, json, collections - no install needed. Check the stdlib before writing it yourself.
  • ipaddress.ip_network("10.20.30.0/24") knows .num_addresses, .hosts(), and membership: ip_address("10.20.30.45") in net. Your Lesson 2 host math, productionized.
  • collections.Counter(vlans).most_common(3) is the top-talkers report in one line.
  • json.dumps(dict) → string, json.loads(string) → dict. This is the wire format of every API in the flagship course.
  • Third-party code comes from PyPI via pip - ALWAYS inside an activated venv ((.venv) in your prompt; pip -V shows which env you're really in).
  • pip freeze > requirements.txt captures your environment; pip install -r requirements.txt rebuilds it anywhere. Reproducibility is a deliverable.
  • Never name a file after a module - json.py, re.py, ipaddress.py in your folder shadows the real one, and the import error will point everywhere but at the filename.
  • Prove it: the graded lab at the end runs in your browser - implement the functions and make every check green.
In this lesson you will:
  • Import from the standard library - ipaddress, collections, json
  • Replace your hand-rolled subnet math with the professional tool
  • Install third-party packages with pip, inside a venv, on purpose
  • Freeze and reproduce environments with requirements.txt
  • Dodge the stdlib-shadowing trap that breaks imports mysteriously

Batteries included: the standard library

Every Python install ships hundreds of modules - no download, just import. Three of them earn permanent spots in a network engineer’s toolbelt:

ipaddress - retire your hand-rolled subnet math

import ipaddress

net = ipaddress.ip_network("10.20.30.0/24")
net.num_addresses                      # 256
len(list(net.hosts()))                 # 254 - and it's right for /31s too
ipaddress.ip_address("10.20.30.45") in net    # True - membership, Lesson 4 style

Eight lessons ago you wrote 2 ** (32 - prefix) - 2, and that was the right way to learn what the bits mean. The professional version handles the edge cases you haven’t hit yet (/31 point-to-points, IPv6), and it validates network boundaries by default: ip_network("10.20.30.1/24") raises ValueError unless you pass strict=False to say “normalize this host address to its network.” You can now read its docs fluently because you know what it’s abstracting.

collections.Counter - counting is a solved problem

from collections import Counter

vlans = [10, 10, 20, 10, 30, 20]
Counter(vlans).most_common(2)          # [(10, 3), (20, 2)]

Top talkers, most-common log messages, duplicate serials - anything you were about to count with a dict-and-loop, Counter does in a line.

json - the wire format of everything

import json

device = {"hostname": "acc-sw01", "ip": "10.20.30.11"}
text = json.dumps(device)              # dict -> string (to a file, an API)
back = json.loads(text)                # string -> dict (from a file, an API)

JSON is nested dicts and lists in text form - which is why Lesson 4 mattered so much. When the flagship course starts calling REST APIs, the responses land in json.loads() and come out as structures you already know how to walk.

pip and PyPI: the wider world

Beyond the standard library sits PyPI - the package index where Netmiko, NAPALM, Nornir, and ~half a million other packages live. pip installs from it:

source .venv/bin/activate        # FIRST. Always.
pip install rich                 # a terminal-formatting library worth meeting
pip list                         # what's installed in THIS venv
Where your imports come from
Rendering diagram…
View diagram source - it's just text (Mermaid). Diagrams-as-code is how modern network docs work; the flagship course has a free module on it.
flowchart TD
  S["your_script.py"] -- "import ipaddress, json" --> STD["standard library<br/>ships with Python"]
  S -- "import netmiko" --> V
  subgraph V [".venv - this project's private packages"]
      SP["site-packages/"]
  end
  PYPI["PyPI<br/>~500k packages"] -- "pip install<br/>(venv ACTIVATED)" --> SP

This is why Lesson 1 made you build a venv before anything else: pip installs into somewhere, and the venv makes that somewhere yours - per-project, disposable, conflict-free. The diagnostic when anything feels off: pip -V prints which environment pip is really pointing at. No (.venv) in your prompt and a path under /usr in that output? Stop and activate.

requirements.txt: reproducibility as a deliverable

pip freeze > requirements.txt    # capture exact versions
pip install -r requirements.txt # rebuild the environment anywhere
Standing on the standard library
Try it yourself (Python runs in your browser)
Output appears here. First run downloads the Python runtime (~10 MB), so give it a few seconds.

Prove it (graded lab)

Write each function in the editor, then Run grader - it runs the lesson’s real checks right here in your browser, nothing to install. Green means the skill is yours, and these are the building blocks the Lesson 10 capstone (netaudit) is assembled from.

Five functions - all standard library, imports provided:

  1. network_size(cidr) - total addresses in a network
  2. usable_count(cidr) - usable hosts, the professional way
  3. ip_in_network(ip, cidr) - membership, boolean
  4. top_vlans(vlan_list, n) - most-common VLANs with counts
  5. device_to_json(device) - serialize an inventory dict (sorted keys)
Graded lab - 5 checks, run right here
Edit the functions above, then Run grader. First run downloads the Python runtime (~10 MB), so give it a few seconds.
Reveal a reference solution
"""Lesson 9 reference solutions. Read after an honest attempt."""

import ipaddress
import json
from collections import Counter


def network_size(cidr):
    return ipaddress.ip_network(cidr).num_addresses


def usable_count(cidr):
    return len(list(ipaddress.ip_network(cidr).hosts()))


def ip_in_network(ip, cidr):
    return ipaddress.ip_address(ip) in ipaddress.ip_network(cidr)


def top_vlans(vlan_list, n):
    return Counter(vlan_list).most_common(n)


def device_to_json(device):
    return json.dumps(device, sort_keys=True)

Read it, close it, then re-type your own version from memory. Wrong turns are where the learning is.

Check your understanding

import json works, but json.dumps(device) raises AttributeError: module "json" has no attribute "dumps". Most likely cause?

1 / 3

Summary

The standard library hands you ipaddress (your subnet math, edge-case-proofed), Counter (counting, solved), and json (the wire format of every API to come) - check it before building. Third-party power arrives via pip from PyPI, always inside an activated venv (pip -V when in doubt), and requirements.txt turns “works on my laptop” into “works on any laptop.” The shadowing trap - naming a file after a famous module - is now one you’ll diagnose in seconds instead of hours. One lesson left: packaging your own code so it imports like the libraries do, plus the capstone that assembles the whole course.