NetAuto Academy

APIs and REST for Network Engineers

Reading Structured JSON Responses

Intermediate11 min read

What you'll learn

  • How response.json() turns an HTTP response body into real Python data
  • Why API JSON doesn't need the parsing send_command() output always did
  • How to extract specific nested fields from a real response
  • That this is the same structured-data skill from Networking Data & Formats, reused
🎓 Teach This Lesson

Listen to a guided explanation of this lesson.

Spoken narration isn't supported in this browser.

No parsing required — it's already structured

"Running Show Commands with Netmiko" made a point of this: send_command()'s output is raw CLI text, and turning it into a usable fact requires writing a parser (is_ntp_synced(), is_vlan_present()). A JSON API response skips that step entirely — the structure is already there.

CLI text (Netmiko)
  1. show ip interface briefraw text output
  2. Write a parseris_ntp_synced(), is_vlan_present()
  3. Now it's usable data
JSON API response
  1. GET /devices/SW1/interfacesreturns JSON
  2. response.json()already a dict/list
  3. Usable data immediately
Quick checkConcept check
Why doesn't a JSON API response need a custom parser the way send_command()'s output did?

response.json(), directly

parse_response.py
import requests

response = requests.get("http://127.0.0.1:8765/devices/SW1/interfaces")
data = response.json()

print(type(data))
print(data)

response.json() returns real Python data — dicts and lists, exactly the shapes 'Working with JSON in Python' and 'Lists & Dictionaries for Network Data' already taught.

output
<class 'dict'>
{'hostname': 'SW1', 'interfaces': [{'name': 'GigabitEthernet1/0/1', 'status': 'up'}, {'name': 'GigabitEthernet1/0/2', 'status': 'down'}]}

A dict with a hostname key and an interfaces key holding a list of dicts — the exact 'list of dictionaries' shape this curriculum has used since Python Lesson 3, arriving over HTTP instead of being built by hand.

Quick checkPredict output
Given the parsed data above, what does data["interfaces"][1]["status"] evaluate to?

Extracting the field you actually need

extract_field.py
response = requests.get("http://127.0.0.1:8765/devices/SW1/interfaces")
data = response.json()

for interface in data["interfaces"]:
  print(interface["name"], "-", interface["status"])

Looping over data['interfaces'] is exactly the same for-loop pattern used on every list of dicts since Python Lesson 4 — devices.csv rows, VLAN lists, and now API response items all follow the same shape.

output
GigabitEthernet1/0/1 - up
GigabitEthernet1/0/2 - down

Real, verified output from this module's mock API.

Quick checkIdentify the correct code
Which line correctly prints just the names of every 'up' interface from the parsed response?

The response's structure is still just a claim

Parsed successfully is not the same as correct

response.json() will happily parse whatever JSON the server actually sent — including a shape that's missing a field your code expects. A KeyError from data["interfaces"] on a response that doesn't have that key is a real, common bug — not a sign that JSON parsing itself is unreliable. This is the same theme Configuration & Template Automation raised about rendered templates: successfully processing something is never the same claim as the something being correct.

Quick checkScenario
A script calls response.json() and then reads data["interfaces"], but the API actually returned {"error": "device not found"} — a 404 response with a different shape entirely. What happens?

Key takeaways

  • response.json() turns an HTTP response body directly into Python dicts/lists — no custom parser needed, unlike raw CLI text from send_command().
  • The resulting shape is the exact 'list of dictionaries' pattern this curriculum has used since Python Lesson 3 — looping, indexing, and key access all work exactly as already learned.
  • A response parsing successfully only proves it was valid JSON — not that it has the fields your code expects. Checking the status code first (Lesson 5) is what actually protects against this.