The two functions that do everything
import json
text = '{"id": 42, "name": "Ada", "tags": ["a", "b"]}'
data = json.loads(text) # str -> dict
data["id"] # 42
type(data["tags"]) # <class 'list'>
back = json.dumps(data) # dict -> str
pretty = json.dumps(data, indent=2, sort_keys=True)That is the whole API for the common case. json.loads converts a string to a Python object; json.dumps converts it back to a JSON string. The file-based variants drop the s: json.load(f) and json.dump(obj, f).
How the types map
- object →
dict, array →list, string →str - number →
intorfloat, depending on whether it has a decimal point true/false→True/False,null→None
Going the other way, dumps accepts dicts, lists, strings, numbers, booleans andNone. Anything else — a datetime, a Decimal, aset, a dataclass — raises TypeError: Object of type X is not JSON serializable. Fix it with default=str for a quick script, or a customJSONEncoder when the shape matters.
Handling double-encoded payloads
raw = '"{\"id\": 42}"' # a JSON string containing JSON
once = json.loads(raw) # '{"id": 42}' -> still a str!
twice = json.loads(once) # {'id': 42} -> now a dict
# defensive version
value = json.loads(raw)
while isinstance(value, str):
value = json.loads(value)This is the single most common surprise when reading logs, Kafka messages or database columns that stored a serialized payload. If loads hands back a str rather than a dict, you have another layer to peel. The converter above unwraps these automatically so you can see the real structure before writing the loop.
Errors worth recognising
Parse failures raise json.JSONDecodeError, a subclass of ValueError, carrying msg, pos, lineno and colno — catch it and log those coordinates rather than the whole payload.Expecting value: line 1 column 1 almost always means an empty string or an HTML error page where you expected JSON. Extra data means several documents concatenated, which is JSON Lines: parse it one line at a time.
Also remember json.dumps escapes non-ASCII by default. Passensure_ascii=False to keep names and emoji readable in the output.
Types the standard library will not serialize
The list is longer than people expect: datetime, date,Decimal, UUID, set, bytes, and any class of your own. Each raises TypeError at dumps time rather than producing something approximate, which is the right default even though it is inconvenient.
For a script, json.dumps(obj, default=str) is enough — it stringifies anything the encoder cannot handle. For an API, be deliberate: subclass JSONEncoder and decide what each type becomes, so a Decimal price does not silently turn into a float and start accumulating rounding errors. Pydantic and the dataclasses.asdict route both handle this for you, which is a large part of why they are so widely used.
Reading a JSON API response
With requests, calling response.json() is the same asjson.loads(response.text) — it will raise if the body is not JSON, which is exactly what happens when the server returns an HTML error page with a 200 status. Checkresponse.status_code or call raise_for_status() first, and wrap the parse so the traceback tells you what arrived instead of just where it failed.
For files large enough to matter, json.load still reads the whole document into memory. Streaming parsers such as ijson walk it incrementally, and JSON Lines — one document per line — is usually the simpler answer: read the file line by line and calljson.loads on each, and memory stays flat regardless of file size.
Naming, briefly
Whether you convert string to JSON Python-side with json.loads,convert a string to JSON object in Python, python string to JSON,convert string to JSON python, or python convert string to JSON — you are calling the same function. The difference is only in what the top-level value turns out to be. The reverse trip, Python JSON to string, is always json.dumps. There is no separate "stringify" in Python, and nothing in the standard library needs installing. Use theonline string to JSON converter above to quickly validate a payload before running it through json.loads in your application.