Pretty print JSON in Python: the json.dumps guide
The one-liner to remember is print(json.dumps(data, indent=2)). json.dumps serializes your object to a JSON string and indent=2 indents every nesting level, turning a wall like {"sizes":[40,41,42],"name":"red sneaker"} into something a human can scan. The same call handles files, API responses and terminal output; the flags around it (sort_keys, ensure_ascii, default) cover the rest of what people need. This page shows the working examples, the indentation choices, and the errors you will actually hit.
The one-liner and what it produces
import json
data = {"name": "red sneaker", "sizes": [40, 41, 42], "in_stock": True, "price": 59.0, "meta": None}
print(json.dumps(data, indent=2))Output, exactly as Python prints it:
{
"name": "red sneaker",
"sizes": [
40,
41,
42
],
"in_stock": true,
"price": 59.0,
"meta": null
}
Three things to notice, because they surprise people on real data. Booleans print lowercase (true), None prints as null, and floats keep their Python form. Lists expand too: a three-element list becomes four lines, whether you like it or not, because indent applies to every container, not just objects. Dropping the indent argument gives a single line with single spaces, like {"name": "red sneaker", "sizes": [40, 41, 42], "in_stock": true, "price": 59.0, "meta": null}, which is fine for logs but hopeless for reading.
To get sorted keys, which makes diffs between two dumps meaningful, add sort_keys=True:
json.dumps(data, indent=2, sort_keys=True)Pretty print a JSON file
In code, read and dump:
import json
with open("data.json") as f:
data = json.load(f)
print(json.dumps(data, indent=2))
To write the pretty version back to disk, use json.dump (no s: it writes to a file object) with the same indent:
with open("data-pretty.json", "w") as f:
json.dump(data, f, indent=2)Without writing any code, the standard library ships a formatter you can run from the terminal:
python -m json.tool data.json
It indents by 4 spaces and validates the file while it formats, so a broken file fails with a clear error instead of formatted output. It also reads stdin, which makes it the quickest way to pretty print an API response:
curl -s https://api.example.com/data | python -m json.toolChoosing the indentation
- indent=2. The common choice, and what you see in most JSON you meet. Use it unless something below contradicts you.
- indent=4. Matches Python's own indentation style, which some teams prefer when JSON lives next to Python source in review.
- indent with a string. Any string works as the unit:
indent="\t"indents with real tabs. Editors and terminals both handle it. - indent=None. Compact single-line output. For machine-to-machine payloads this is what you want anyway; pretty formatting is for humans.
One separator nuance bites people comparing outputs: with indent set, items separate with a bare comma and the spacing comes from newlines; without it, the default separators are a comma plus space after items. The bytes differ between the two styles, so byte-level comparisons of formatted files should pin both indent and separators explicitly.
The errors you will actually hit
- "Object of type datetime is not JSON serializable". The classic. JSON has no date type, so
json.dumpsrefuses and names the offending type for you. For quick output,json.dumps(data, default=str)stringifies anything it does not recognize: a datetime becomes something like"2026-10-11 20:00:00", microseconds and all when they exist. For a format other people will parse, serialize dates yourself (ISO 8601 viadatetime.isoformat()) instead of lettingstrimprovise. - Non-ASCII characters look wrong. By default
json.dumpsescapes every non-ASCII character: a café prints ascaf\u00e9. It is valid JSON either way, but for human-readable output addensure_ascii=Falseand the real letters survive. - The file you read is not valid JSON.
json.loadraisesjson.decoder.JSONDecodeErrorwith line and column. The usual suspects: trailing commas (JSON has none), single quotes (JSON wants double), and pasted output that was never JSON to begin with.
Frequently Asked Questions
How do I pretty print JSON in Python?
Use json.dumps with the indent argument: print(json.dumps(data, indent=2)). json.dumps turns the object into a JSON string, and indent=2 adds two spaces of indentation per nesting level, so nested objects and lists print one element per line instead of one unreadable line.
What does indent do in json.dumps?
It sets the number of spaces per nesting level: indent=2 is the common choice, indent=4 matches Python's own style, and indent accepts a string such as a tab. One side effect worth knowing: once indent is set, the default separator between items changes from a comma plus space to a bare comma, because the newlines carry the spacing now. Arrays also expand, one element per line, even when they are short.
How do I pretty print a JSON file in Python?
Two ways. In code: json.load(open('data.json')) reads the file, then json.dumps(data, indent=2) prints it pretty. On the command line: python -m json.tool data.json does the same thing without writing any code, and piping curl output into it (curl -s URL | python -m json.tool) pretty prints an API response as it arrives.