Instiq
Chapter 1 · Software Development and Design·v1.0.0·Updated 7/20/2026·~16 min

What's changed: Initial version

1.1Data formats and parsing

Key points

Covers the traits of the three data-interchange formats JSON, YAML, and XML, and the judgment of parsing each into Python data structures (dict, list) to extract values, framed as interpreting and diagnosing given artifacts: "how do I read this response/config and where do I pull a value from?" and "why did the load fail?"

The first step in automation is reading data correctly from devices and APIs. In DevNet practice, what matters is less memorizing notation than instantly judging "how do I extract the value I want from this JSON API response?" and "why will this YAML playbook not load?" This section first fixes when to use each of the three formats, then covers parsing them into Python dict (key-to-value mapping) and list (ordered sequence) to pull values out of nested structures, learned as the diagnosis of reading real responses.

1.1.1Traits of the three data formats

  • A machine-readable format built from {} objects (key-value pairs) and [] arrays. Strings must be in double quotes "...", true/false/null are lowercase, and trailing commas are not allowed. It is the de-facto standard for REST API request/response bodies, concise as in {"name": "r1", "up": true}.
  • A human-readable format that expresses hierarchy through indentation (spaces). It uses key: value and lists whose items start with - at line head. Tabs are forbidden (spaces only), and the amount of indentation *is* the structure, so it breaks easily. It is heavily used in Ansible playbooks and config files, and is a superset of JSON (valid JSON is valid YAML).
  • A verbose but strict format that nests elements with opening/closing tags <tag>...</tag> and can carry attributes and namespaces. It is still used in model-driven device management such as NETCONF responses. It is heavier to hand-write than JSON/YAML but pairs well with schema validation.

1.1.2Parsing into Python data structures

  • A JSON string is turned into a dict/list with json.loads(text), and a REST response with requests resp.json(). An object {} becomes a dict, an array [] a list, strings/numbers/booleans become Python str/int,float/bool, and null becomes None. Serializing back from Python is json.dumps(obj).
  • YAML is read into Python dict/list with yaml.safe_load(text) (use the safe safe_load, not load). Extracting a nested value is a chain of keys and indexes: data["devices"][0]["name"] means "the name of the first element of the devices list." The trick is to first determine whether the outermost thing is a dict or a list; getting that wrong yields a KeyError or TypeError.
Exam point

Most-tested: JSON {}=dict, []=list, double quotes required, no trailing comma; YAML uses indentation for hierarchy, no tabs, - marks a list; XML nests tags and lingers in NETCONF; resp.json()/json.loads/yaml.safe_load give dict/list, null->None. Questions mostly arrive as judgment: "which expression extracts this value?" and "why did the load fail?"

A colleague asks for help: their script, meant to "print whether Gi0/0 of the first router in a device list is enabled," crashes with an exception. The API returns this JSON: {"devices": [{"name": "r1", "interfaces": [{"name": "Gi0/0", "enabled": true}]}]}. Reading the structure: the outermost thing is a dict, the value of key devices is a list, its first element is the router dict, and its interfaces is again a list. So you reach the target with data["devices"][0]["interfaces"][0]["enabled"], walking key -> index -> key -> index -> key. The colleague wrote data["devices"]["interfaces"], subscripting a list with a string key, which raised a TypeError—the cause was misreading "outer is dict, inside is list." Next, another team holding the same config in YAML found that yaml.safe_load returned the whole thing as a single string. The causes were a tab mixed into the indentation (YAML forbids tabs) and a missing space after the - in - name: Gi0/0, so it was not parsed as a list item. The right judgment here is not "let us rewrite it as JSON" but to replace tabs with spaces and align the indentation. In short, the strict per-format rules (JSON double quotes and no trailing comma, YAML space indentation) plus reading whether the parsed result is a dict or a list, one level at a time, are what isolate automation-script bugs fastest.

AspectJSONYAMLXML
FocusMachine-readable, conciseHuman-readableStrict, validation-friendly
Hierarchyvia `{}` and `[]`Indentation (spaces)Nested tags
GotchaNo trailing comma, double quotesNo tabs, space after `- `Verbose closing tags/namespaces
Typical useREST API bodiesAnsible/config filesNETCONF, etc.
Warning

Trap: "A JSON array [] becomes a Python dict" is wrong—[] is a list, {} is a dict. List elements are taken by integer index, not a string key (data["devices"][0]). Also wrong: "YAML may be indented with tabs"—tabs are forbidden, and broken indentation makes yaml.safe_load return an unintended string or structure. Note too that resp.json() does not always return a dict: if the response is an array, you get a list.

Traits of JSON/YAML/XML and the steps to parse into dict/list.
Reading a response correctly to extract a value

1.1.3Section summary

  • JSON is {}=dict/[]=list, double quotes required, no trailing comma; YAML uses space indentation with no tabs; XML nests tags and lingers in NETCONF
  • Parse into Python dict/list with resp.json()/json.loads/yaml.safe_load, and null becomes None
  • Reach nested values by chaining keys and indexes (data["devices"][0]["enabled"]); determining whether each level is a dict or list is the key to diagnosis

Sign in to track progress — Log in.

Quick check

(just a quick review)

Q1. An API returned the JSON `{"devices": [{"name": "r1", "interfaces": [{"name": "Gi0/0", "enabled": true}]}]}`, already parsed into `data`. Which expression correctly extracts whether Gi0/0 of the first device is enabled?

Q2. Loading a person's Ansible playbook (YAML) with `yaml.safe_load` does not yield the expected dict/list but returns the value as a single string. What is the most appropriate first thing to check and fix?

Q3. A config file written as the following JSON caused the parser to error: `{"vlan": 10, "name": "sales",}`. What is the most appropriate cause of the error?

Check your understandingPractice questions for Chapter 1: Software Development and Design