JSON in Python: Complete Guide with json Module
Master JSON in Python! Learn how to parse, generate, and work with JSON data using Python's built-in json module. Includes practical examples and best practices.
Introduction to Python's json Module
Python provides a built-in json module for encoding and decoding JSON data. The main functions are:
json.loads()- Parse JSON string to Python dict/listjson.dumps()- Convert Python object to JSON stringjson.load()- Read JSON from a filejson.dump()- Write JSON to a file
Parsing JSON Strings - json.loads()
Basic Usage
import json
# JSON string
json_string = '{"name": "John", "age": 30, "city": "New York"}'
# Parse JSON to Python dictionary
data = json.loads(json_string)
print(data['name']) # Output: John
print(data['age']) # Output: 30
print(type(data)) # Output: <class 'dict'>
Parsing JSON Arrays
import json
json_array = '[{"id": 1, "name": "Product 1"}, {"id": 2, "name": "Product 2"}]'
products = json.loads(json_array)
for product in products:
print(f"{product['id']}: {product['name']}")
Error Handling
import json
def safe_parse_json(json_string):
try:
return json.loads(json_string)
except json.JSONDecodeError as e:
print(f"Invalid JSON: {e}")
return None
# This will handle the error gracefully
data = safe_parse_json('{"invalid json}')
Converting Python to JSON - json.dumps()
Basic Conversion
import json
user = {
"name": "John Doe",
"age": 30,
"email": "john@example.com",
"is_active": True
}
# Convert to JSON string
json_string = json.dumps(user)
print(json_string)
# Output: {"name": "John Doe", "age": 30, "email": "john@example.com", "is_active": true}
Pretty Printing
import json
data = {
"name": "John",
"hobbies": ["reading", "coding"],
"address": {"city": "New York", "zip": "10001"}
}
# Pretty print with indentation
pretty_json = json.dumps(data, indent=2)
print(pretty_json)
"""
{
"name": "John",
"hobbies": [
"reading",
"coding"
],
"address": {
"city": "New York",
"zip": "10001"
}
}
"""
Sorting Keys
import json
data = {"zebra": 1, "apple": 2, "banana": 3}
# Sort keys alphabetically
json_string = json.dumps(data, indent=2, sort_keys=True)
print(json_string)
"""
{
"apple": 2,
"banana": 3,
"zebra": 1
}
"""
Reading and Writing JSON Files
Reading JSON from a File
import json
# Read JSON file
with open('data.json', 'r') as file:
data = json.load(file)
print(data)
# Alternative: Read as string first
with open('data.json', 'r') as file:
json_string = file.read()
data = json.loads(json_string)
Writing JSON to a File
import json
data = {
"users": [
{"id": 1, "name": "John"},
{"id": 2, "name": "Jane"}
]
}
# Write to JSON file
with open('output.json', 'w') as file:
json.dump(data, file, indent=2)
# Or dump to string first
with open('output.json', 'w') as file:
json_string = json.dumps(data, indent=2)
file.write(json_string)
Working with Python Data Types
Data Type Conversion Table
Python → JSON
dict → object
list, tuple → array
str → string
int, float → number
True → true
False → false
None → null
Example Conversion
import json
python_data = {
"string": "Hello",
"number": 42,
"float": 3.14,
"boolean": True,
"null_value": None,
"list": [1, 2, 3],
"nested": {"key": "value"}
}
json_string = json.dumps(python_data, indent=2)
print(json_string)
Working with APIs
Making GET Requests
import json
import requests
# Fetch JSON from API
response = requests.get('https://api.example.com/users')
# Parse JSON response
if response.status_code == 200:
users = response.json() # Same as json.loads(response.text)
for user in users:
print(user['name'])
Making POST Requests
import json
import requests
# Data to send
new_user = {
"name": "Jane Doe",
"email": "jane@example.com"
}
# Send JSON data
response = requests.post(
'https://api.example.com/users',
json=new_user # Automatically converts to JSON
)
# Or manually with headers
response = requests.post(
'https://api.example.com/users',
data=json.dumps(new_user),
headers={'Content-Type': 'application/json'}
)
Custom JSON Encoding
Encoding Custom Objects
import json
from datetime import datetime
class User:
def __init__(self, name, created_at):
self.name = name
self.created_at = created_at
# Custom encoder
class UserEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, User):
return {
'name': obj.name,
'created_at': obj.created_at.isoformat()
}
if isinstance(obj, datetime):
return obj.isoformat()
return super().default(obj)
user = User("John", datetime.now())
json_string = json.dumps(user, cls=UserEncoder, indent=2)
print(json_string)
Advanced Techniques
Handling Large JSON Files
import json
# For large files, use streaming
def process_large_json(filename):
with open(filename, 'r') as file:
# Load incrementally
for line in file:
try:
data = json.loads(line)
# Process each line
yield data
except json.JSONDecodeError:
continue
Validating JSON Structure
import json
def validate_user_data(json_string):
try:
data = json.loads(json_string)
# Check required fields
required_fields = ['name', 'email', 'age']
for field in required_fields:
if field not in data:
return False, f"Missing field: {field}"
# Validate types
if not isinstance(data['age'], int):
return False, "Age must be an integer"
return True, "Valid"
except json.JSONDecodeError as e:
return False, f"Invalid JSON: {e}"
Pro Tip: Always validate JSON data from external sources using our free online JSON validator before processing!
Summary
- Use
json.loads()for parsing JSON strings - Use
json.dumps()for creating JSON strings - Use
json.load()andjson.dump()for file operations - Always handle
JSONDecodeErrorexceptions - Use
indentparameter for readable output - Create custom encoders for complex objects