Learn the concept
HTTP connects a client request to a server response. A request includes a method, path, headers, and sometimes a body. A response includes a status, headers, and a body. JSON is a common body format, not a guarantee that every response is valid JSON.
Differentiate transport failure, non-success HTTP status, malformed content, and a valid response with a domain-level error. A timeout does not tell you whether a remote write completed. Keep response parsing separate from business decisions.
An API contract documents required fields, error behavior, and authentication. Never put server credentials in a browser or mobile application. The following example constructs a request without sending it; real calls should have explicit deadlines and target only services you are authorized to use.
Run and inspect
import json
from urllib.request import Request
body = json.dumps({"question": "What is an API?"}).encode("utf-8")
request = Request("http://localhost:8000/answer", data=body, headers={"Content-Type": "application/json"}, method="POST")
assert request.get_method() == "POST"
assert json.loads(request.data)["question"] == "What is an API?"
Your exercise
Define a POST request and three response fixtures: success, validation failure, and upstream timeout. Write a parser that distinguishes them.
Check your understanding
A non-JSON error body does not crash the application as if it were a successful response.