jsonpythontutorialcsvapi

JSON in Python: Complete Guide with Examples

·9 min read

JSON in Python: The Complete Guide

Python's json module is part of the standard library — no installation needed. It handles everything from parsing API responses to reading config files to preparing data for machine learning. This guide covers every pattern you will use in real projects.

json.loads() — Parse a JSON String

json.loads() takes a JSON string and returns a Python object: dict, list, str, int, float, bool, or None.

python
import json

json_str = '{"name": "Ravi", "age": 28, "active": true, "score": null}'
data = json.loads(json_str)

print(data["name"])    # Ravi
print(data["age"])     # 28
print(data["active"])  # True (Python bool)
print(data["score"])   # None (Python None)
print(type(data))      # <class 'dict'>

JSON true becomes Python True. JSON false becomes Python False. JSON null becomes Python None.

Always wrap json.loads() in try/except for production code:

python
try:
    data = json.loads(json_str)
except json.JSONDecodeError as e:
    print(f"Invalid JSON: {e.msg} at line {e.lineno}, column {e.colno}")

json.dumps() — Convert to a JSON String

json.dumps() serializes a Python value to a JSON string.

python
data = {"name": "Ravi", "age": 28, "verified": True, "score": None}
json_str = json.dumps(data)
# '{"name": "Ravi", "age": 28, "verified": true, "score": null}'

Add indent for human-readable output:

python
print(json.dumps(data, indent=2))
# {
#   "name": "Ravi",
#   "age": 28,
#   "verified": true,
#   "score": null
# }

Sort keys alphabetically:

python
json.dumps(data, indent=2, sort_keys=True)

Preserve non-ASCII characters (Devanagari, Gujarati, emojis) instead of escaping them:

python
data = {"city": "સુરત"}
json.dumps(data, ensure_ascii=False)
# '{"city": "સુરત"}'

Without ensure_ascii=False the output would be `{"city": "\u0ab8\u0ac1\u0ab0\u0aa4"}` — technically correct but unreadable.

Reading a JSON File

Use json.load() (without the s) to read directly from a file object:

python
import json

with open("config.json", "r", encoding="utf-8") as f:
    config = json.load(f)

db_host = config["database"]["host"]
db_port = config["database"]["port"]
print(f"Connecting to {db_host}:{db_port}")

Always specify encoding="utf-8" — especially on Windows where the default encoding is not UTF-8.

Writing a JSON File

Use json.dump() to write directly to a file object:

python
import json

users = [
    {"id": 1, "name": "Ravi",  "city": "Surat"},
    {"id": 2, "name": "Priya", "city": "Ahmedabad"},
]

with open("users.json", "w", encoding="utf-8") as f:
    json.dump(users, f, indent=2, ensure_ascii=False)

Fetching JSON from a REST API

With the standard library only:

python
import json
import urllib.request

url = "https://api.example.com/users/1"
with urllib.request.urlopen(url) as response:
    data = json.loads(response.read().decode("utf-8"))
    print(data["name"])

With the requests library (recommended — pip install requests):

python
import requests

response = requests.get("https://api.example.com/users/1")
response.raise_for_status()  # raises HTTPError for 4xx/5xx

data = response.json()       # calls json.loads() automatically
print(data["name"])

Posting JSON to an API

python
import requests

payload = {"name": "Ravi", "email": "ravi@example.com", "city": "Surat"}

response = requests.post(
    "https://api.example.com/users",
    json=payload,  # automatically serializes and sets Content-Type header
    headers={"Authorization": "Bearer your_token_here"},
)
response.raise_for_status()

result = response.json()
print(f"Created user with id: {result['id']}")

Using json=payload in requests.post() automatically calls json.dumps() and sets the Content-Type: application/json header — no manual stringifying needed.

Convert JSON Array to CSV with pandas

For data analysis, convert a JSON array of objects to a pandas DataFrame and export as CSV:

python
import json
import pandas as pd

with open("users.json", "r", encoding="utf-8") as f:
    users = json.load(f)  # expects a list of dicts

df = pd.DataFrame(users)
df.to_csv("users.csv", index=False, encoding="utf-8")
print(df.head())

For nested JSON, use pandas json_normalize to flatten it automatically:

python
from pandas import json_normalize

with open("orders.json", "r") as f:
    data = json.load(f)

# Flattens nested keys: address.city, address.street, etc.
df = json_normalize(data, sep=".")
df.to_csv("orders_flat.csv", index=False)
print(df.columns.tolist())

You can also convert JSON directly without saving to disk using JSONKit's JSON to CSV converter at /json-to-csv for a quick one-off conversion with live table preview.

Handling Dates in JSON

Python's datetime objects are not JSON-serializable by default. Use a custom encoder:

python
import json
from datetime import datetime, date

class DateEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, (datetime, date)):
            return obj.isoformat()
        return super().default(obj)

data = {"event": "Launch", "date": datetime(2025, 5, 1, 10, 30)}
json_str = json.dumps(data, cls=DateEncoder)
# '{"event": "Launch", "date": "2025-05-01T10:30:00"}'

To parse ISO dates back to datetime objects when loading:

python
from datetime import datetime

def parse_dates(obj):
    for key, value in obj.items():
        if isinstance(value, str):
            try:
                obj[key] = datetime.fromisoformat(value)
            except ValueError:
                pass
    return obj

data = json.loads(json_str, object_hook=parse_dates)
print(type(data["date"]))  # <class 'datetime.datetime'>

Pretty-Print Any JSON for Debugging

python
import json

# Pretty-print a dict
print(json.dumps(api_response, indent=2, ensure_ascii=False))

# Pretty-print a JSON file to stdout
import sys
with open("data.json") as f:
    json.dump(json.load(f), sys.stdout, indent=2)

Or paste any JSON into JSONKit's formatter at /json-formatter for interactive exploration with collapsible tree view, syntax highlighting, and file download.

Try JSON Formatter

Format JSON output from Python's json.dumps() for easy inspection.