Talking to an API · practice
Check Status Before JSON
A JSON error envelope is still an unsuccessful HTTP response. Code that decodes first can accidentally treat {"error": ...} as ordinary catalog data.
Replace the temporary status read in request_json with the status boundary:
response.raise_for_status()
return response.json()
The order is the contract. A 200 reaches json(). /items/99, the deliberate /scenarios/not-found, and /scenarios/server-error raise HTTPError before their bodies can be mistaken for success.
Do not catch anything inside request_json. It cannot decide what a command should print or which exit status the caller needs. At a command boundary, the narrow pattern is:
try:
document = request_json("/items/99")
except requests.HTTPError as exc:
print(exc.response.status_code)
Read the status from exc.response.status_code, not from
Try both routes against the live internal service if you want to see the real thing. Then write the fake-response version, because that is the one that will still behave identically in six months on a machine with no network.
Why call raise_for_status() before json()?
If the ordering rule feels arbitrary, ask Monty to show what happens when a 404’s JSON body gets decoded as though it were a successful page. Seeing the wrong data arrive successfully is more convincing than the rule.
Task
Change request_json so it calls response.raise_for_status() before response.json() and catches nothing. Preserve the fixed URL, exact header, forwarded