Of course! Formatting JSON in Python is a common task, and the primary tool for this is the built-in json module. The most important function for pretty-printing is json.dumps().

Here’s a complete guide, from the basics to more advanced formatting options.
The Short and Sweet Answer: json.dumps()
The json.dumps() (dump string) function converts a Python object into a JSON formatted string. To make it "pretty," you use the indent parameter.
import json
# A Python dictionary (our data)
data = {
"name": "John Doe",
"age": 30,
"isStudent": False,
"courses": [
{"title": "History", "credits": 3},
{"title": "Math", "credits": 4}
],
"address": {
"street": "123 Main St",
"city": "Anytown"
}
}
# Convert the Python object to a nicely formatted JSON string
# The 'indent=4' argument adds 4 spaces for each level of nesting.
pretty_json_string = json.dumps(data, indent=4)
print(pretty_json_string)
Output:
{
"name": "John Doe",
"age": 30,
"isStudent": false,
"courses": [
{
"title": "History",
"credits": 3
},
{
"title": "Math",
"credits": 4
}
],
"address": {
"street": "123 Main St",
"city": "Anytown"
}
}
Detailed Breakdown of json.dumps() Parameters
The json.dumps() function is powerful. Here are the most useful parameters for formatting:
indent: Control Whitespace
This is the key to pretty-printing. It defines the number of spaces to use for indentation.
indent=4: The most common choice, providing good readability.indent=2: A more compact style, often used in web APIs.indent=None: This is the default. It produces a compact, single-line string with no whitespace (except where necessary). This is ideal for data transmission.
import json
data = {"name": "Jane", "active": True, "tags": ["a", "b", "c"]}
# Compact (default)
print("--- Compact ---")
compact_json = json.dumps(data)
print(compact_json)
# Pretty with indent=2
print("\n--- Indent 2 ---")
pretty_json_2 = json.dumps(data, indent=2)
print(pretty_json_2)
# Pretty with indent=4
print("\n--- Indent 4 ---")
pretty_json_4 = json.dumps(data, indent=4)
print(pretty_json_4)
Output:
--- Compact ---
{"name": "Jane", "active": true, "tags": ["a", "b", "c"]}
--- Indent 2 ---
{
"name": "Jane",
"active": true,
"tags": [
"a",
"b",
"c"
]
}
--- Indent 4 ---
{
"name": "Jane",
"active": true,
"tags": [
"a",
"b",
"c"
]
}
sort_keys: Sort Dictionary Keys
For consistent and predictable output, especially for testing or diffing, you can sort the keys of all dictionaries alphabetically.
import json
data = {"zebra": "last", "apple": "first", "banana": "middle"}
# Unsorted keys
print("--- Unsorted ---")
print(json.dumps(data, indent=2))
# Sorted keys
print("\n--- Sorted ---")
print(json.dumps(data, indent=2, sort_keys=True))
Output:
--- Unsorted ---
{
"zebra": "last",
"apple": "first",
"banana": "middle"
}
--- Sorted ---
{
"apple": "first",
"banana": "middle",
"zebra": "last"
}
separators: Control Compactness
By default, json.dumps() adds a space after the colon () and comma (). You can customize this with the separators tuple, which takes the form (item_separator, key_separator).
- is the default.
- is the most compact format, removing all unnecessary whitespace.
This is useful when you need the smallest possible JSON string without full pretty-printing.
import json
data = {"name": "Bob", "value": 123}
# Default separators
print("--- Default Separators ---")
print(json.dumps(data))
# Compact separators (no spaces)
print("\n--- Compact Separators ---")
print(json.dumps(data, separators=(',', ':')))
Output:
--- Default Separators ---
{"name": "Bob", "value": 123}
--- Compact Separators ---
{"name":"Bob","value":123}
ensure_ascii: Handle Non-ASCII Characters
By default, json.dumps() escapes all non-ASCII characters (like or ) to their \uXXXX Unicode escape sequences. If you want to output the actual characters, set ensure_ascii=False.
import json
data = {"city": "São Paulo", "greeting": "Café"}
# Default (ASCII-safe)
print("--- Default (ASCII) ---")
print(json.dumps(data))
# Preserve non-ASCII characters
print("\n--- Non-ASCII ---")
print(json.dumps(data, ensure_ascii=False))
Output:
--- Default (ASCII) ---
{"city": "S\u00e3o Paulo", "greeting": "Caf\u00e9"}
--- Non-ASCII ---
{"city": "São Paulo", "greeting": "Café"}
Writing Formatted JSON to a File
To save your formatted JSON to a file, use json.dump(). It's similar to dumps() but writes directly to a file object instead of returning a string. **Crucially, you must open the file in write mode ('w') and specify the encoding, usually 'utf-8'.
import json
data = {
"user": "admin",
"permissions": ["read", "write", "execute"],
"settings": {
"theme": "dark",
"notifications": True
}
}
# Use a 'with' statement for safe file handling
with open('config.json', 'w', encoding='utf-8') as f:
# Use indent=4 for pretty-printing
json.dump(data, f, indent=4, ensure_ascii=False)
print("Successfully wrote formatted JSON to config.json")
This will create a file named config.json with the nicely formatted JSON content.
Common Pitfalls and How to Fix Them
TypeError: Object of type ... is not JSON serializable
This error occurs when your Python object contains a type that the json module doesn't know how to convert (e.g., a datetime object, a custom class, or a NumPy array).
Solution: You need to create a custom "serializer" function that tells json how to handle these special types.
import json
from datetime import datetime
class User:
def __init__(self, name, created_at):
self.name = name
self.created_at = created_at
# An object that cannot be serialized by default
user = User("Alice", datetime.now())
def custom_serializer(obj):
"""Custom JSON serializer for objects not natively serializable."""
if isinstance(obj, datetime):
return obj.isoformat() # Convert datetime to an ISO 8601 string
raise TypeError(f"Object of type {type(obj)} is not JSON serializable")
# Use the 'default' argument to pass your custom function
try:
json_string = json.dumps(user, default=custom_serializer, indent=2)
print(json_string)
except TypeError as e:
print(e)
Output:
{
"name": "Alice",
"created_at": "2025-10-27T10:30:00.123456"
}
Summary Table
| Function/Parameter | Purpose | Example |
|---|---|---|
json.dumps() |
Converts a Python object to a JSON string. | json_str = json.dumps(my_dict) |
json.dump() |
Converts a Python object and writes it to a file. | json.dump(my_dict, file_object) |
indent |
Adds whitespace for pretty-printing. | json.dumps(data, indent=4) |
sort_keys |
Sorts dictionary keys alphabetically. | json.dumps(data, sort_keys=True) |
separators |
Controls compactness by defining separators. | json.dumps(data, separators=(',', ':')) |
ensure_ascii |
Preserves non-ASCII characters. | json.dumps(data, ensure_ascii=False) |
default |
Provides a custom function for non-serializable objects. | json.dumps(data, default=my_serializer) |
