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.

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, networks that don’t start on a boundary) — and 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": "den-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.

Exercises (graded)

cd labs/python-foundations/lesson09
pytest -q

Five functions in exercises.py — 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)
✅ 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.