How to Parse JSON in Python (With Examples)
Imad Uddin
Full Stack Developer

Working with JSON in Python is something you'll do constantly if you're building anything that talks to an API, reads configuration files, or processes data from the web. Python makes it ridiculously easy. The built-in
jsonI'll walk through exactly how to parse JSON in Python, starting from the basics and moving into the real world scenarios you'll actually encounter. Simple JSON strings, reading from files, handling messy nested data from an API response, error handling, it's all covered with runnable examples.
The Basics: json.loads() for Strings
The most common way to parse JSON in Python is using
json.loads()Here's the simplest possible example:
Pythonimport json json_string = '{"name": "Alice", "age": 30, "city": "New York"}' data = json.loads(json_string) print(data) print(data["name"]) print(data["age"])
Output:
{'name': 'Alice', 'age': 30, 'city': 'New York'} Alice 30
That's it. The
json.loads()data["name"]The JSON data types map to Python types automatically:
| JSON Type | Python Type |
|---|---|
| object | dict |
| array | list |
| string | str |
| number (int) | int |
| number (float) | float |
| true | True |
| false | False |
| null | None |
So if your JSON contains an array, you get a Python list. If it contains
nullNoneReading JSON from a File: json.load()
When your JSON is in a file rather than a string, use
json.load()Pythonimport json with open("config.json", "r") as file: data = json.load(file) print(data)
The
with open()json.load()Here's what a typical
config.jsonJSON{ "database": { "host": "localhost", "port": 5432, "name": "myapp" }, "debug": true, "allowed_hosts": ["localhost", "127.0.0.1"] }
And the Python code to read and use it:
Pythonimport json with open("config.json", "r") as file: config = json.load(file) db_host = config["database"]["host"] db_port = config["database"]["port"] debug_mode = config["debug"] print(f"Connecting to {db_host}:{db_port}") print(f"Debug mode: {debug_mode}")
Output:
Connecting to localhost:5432 Debug mode: True
Notice how you can access nested values by chaining the keys:
config["database"]["host"]Handling JSON Arrays
Not all JSON starts with an object. Sometimes you'll get an array at the top level, especially when working with API responses that return lists of items.
Pythonimport json json_string = ''' [ {"id": 1, "name": "Product A", "price": 29.99}, {"id": 2, "name": "Product B", "price": 49.99}, {"id": 3, "name": "Product C", "price": 19.99} ] ''' products = json.loads(json_string) for product in products: print(f"{product['name']}: ${product['price']}")
Output:
Product A: $29.99 Product B: $49.99 Product C: $19.99
The
json.loads()Error Handling: What Happens When JSON Is Invalid
If you try to parse invalid JSON, Python raises a
json.JSONDecodeErrorPythonimport json bad_json = '{"name": "Alice", "age": 30,}' # trailing comma is invalid try: data = json.loads(bad_json) except json.JSONDecodeError as e: print(f"Failed to parse JSON: {e}")
Output:
Failed to parse JSON: Expecting property name enclosed in double quotes: line 1 column 32 (char 31)
The error message tells you exactly where the problem is: line 1, column 32. This is useful for debugging, especially with larger JSON documents.
A safer pattern for production code:
Pythonimport 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 # Usage data = safe_parse_json('{"valid": "json"}') if data: print(data) data = safe_parse_json('not json at all') if data is None: print("Parsing failed, handle accordingly")
Wrapping the parse in a function with error handling makes your code more resilient. You can decide what to do when parsing fails: return
NoneParsing JSON from an API Response
One of the most common real world uses when working with JSON in Python is parsing API responses. The
requestspip install requests.json()Pythonimport requests response = requests.get("https://api.github.com/users/torvalds") if response.status_code == 200: user_data = response.json() print(f"Name: {user_data['name']}") print(f"Location: {user_data['location']}") print(f"Public repos: {user_data['public_repos']}") else: print(f"Request failed with status {response.status_code}")
The
response.json()json.loads(response.text)Always check the status code before parsing. If the request fails (4xx or 5xx status), the response body might not be valid JSON, or it might be an error message in a different format.
Working with Nested JSON
Real world JSON is often deeply nested. API responses from services like Stripe, Twilio, or AWS can have multiple levels of nested objects and arrays. Knowing how to navigate this structure efficiently is important.
Here's an example of nested JSON you might get from a weather API:
Pythonimport json weather_json = ''' { "location": { "city": "San Francisco", "country": "US", "coordinates": { "lat": 37.7749, "lon": -122.4194 } }, "current": { "temp": 62, "humidity": 75, "conditions": "Partly Cloudy" }, "forecast": [ {"day": "Monday", "high": 65, "low": 52}, {"day": "Tuesday", "high": 68, "low": 54}, {"day": "Wednesday", "high": 63, "low": 50} ] } ''' weather = json.loads(weather_json) # Access nested object values city = weather["location"]["city"] lat = weather["location"]["coordinates"]["lat"] current_temp = weather["current"]["temp"] print(f"Current temperature in {city}: {current_temp}°F") print(f"Latitude: {lat}") # Iterate over nested array print("\nForecast:") for day in weather["forecast"]: print(f" {day['day']}: High {day['high']}°F, Low {day['low']}°F")
Output:
Current temperature in San Francisco: 62°F Latitude: 37.7749 Forecast: Monday: High 65°F, Low 52°F Tuesday: High 68°F, Low 54°F Wednesday: High 63°F, Low 50°F
The key is understanding that each level of nesting is just another dictionary or list access.
weather["location"]weather["location"]["coordinates"]Safely Accessing Nested Keys
When you're not sure if a key exists, accessing it directly will raise a
KeyError.get()Pythonimport json data = json.loads('{"user": {"name": "Alice"}}') # This will raise KeyError if "email" doesn't exist # email = data["user"]["email"] # Safe access with .get() email = data["user"].get("email", "No email provided") print(email) # Output: No email provided # For deeply nested access, check each level location = data.get("user", {}).get("location", {}).get("city", "Unknown") print(location) # Output: Unknown
The pattern
data.get("key", {}).get()Parsing JSON with Custom Object Conversion
Sometimes you want to convert JSON directly into a custom Python class rather than a dictionary. The
json.loads()object_hookPythonimport json class User: def __init__(self, name, email, age): self.name = name self.email = email self.age = age def __repr__(self): return f"User({self.name}, {self.email}, {self.age})" def user_decoder(obj): if "name" in obj and "email" in obj and "age" in obj: return User(obj["name"], obj["email"], obj["age"]) return obj json_string = '{"name": "Bob", "email": "bob@example.com", "age": 25}' user = json.loads(json_string, object_hook=user_decoder) print(user) print(type(user)) print(user.name)
Output:
User(Bob, bob@example.com, 25) <class '__main__.User'> Bob
The
object_hookCommon Mistakes and How to Avoid Them
Mistake 1: Using json.load() on a string
Python# Wrong data = json.load('{"name": "Alice"}') # TypeError # Correct data = json.loads('{"name": "Alice"}') # Use loads() for strings
Remember:
load()loads()Mistake 2: Forgetting that JSON keys must be strings
In Python dictionaries, keys can be integers, tuples, or other hashable types. In JSON, keys must always be strings.
Python# This Python dict has an integer key python_dict = {1: "one", 2: "two"} # Converting to JSON will turn the key into a string json_string = json.dumps(python_dict) print(json_string) # {"1": "one", "2": "two"} # Parsing it back gives you string keys parsed = json.loads(json_string) print(parsed["1"]) # "one" print(parsed[1]) # KeyError!
Mistake 3: Assuming the JSON structure without checking
API responses can change. Fields can be missing. Always validate or use safe access patterns.
Python# Fragile code that assumes structure name = data["user"]["profile"]["display_name"] # Safer approach name = data.get("user", {}).get("profile", {}).get("display_name", "Anonymous")
Performance Tip: Parsing Large JSON Files
If you're working with very large JSON files (hundreds of megabytes or more), loading the entire file into memory with
json.load()For large files, consider using
ijsonpip install ijsonPythonimport ijson with open("large_file.json", "rb") as file: for item in ijson.items(file, "item"): process(item) # Handle one item at a time
This streams through the file without loading it all into memory. It's more complex to use than
json.load()For most everyday use cases, the standard
jsonQuick Reference
Pythonimport json # Parse JSON string to Python object data = json.loads('{"key": "value"}') # Parse JSON file to Python object with open("file.json") as f: data = json.load(f) # Convert Python object to JSON string json_string = json.dumps(data) # Write Python object to JSON file with open("output.json", "w") as f: json.dump(data, f) # Pretty print with indentation json_string = json.dumps(data, indent=2) # Handle parsing errors try: data = json.loads(maybe_json) except json.JSONDecodeError: print("Invalid JSON")
Wrapping Up
Parsing JSON in Python comes down to two functions for 99% of use cases:
json.loads()json.load()The key things to remember:
- Import the module (it's built in, no installation needed)
json - Use for strings,
loads()for filesload() - Wrap parsing in try/except when handling untrusted data
- Use for safe access to keys that might not exist
.get() - JSON objects become dictionaries, arrays become lists
That covers most of what you'll need for everyday JSON parsing in Python. The
jsonRelated Guides
Need to validate your JSON before parsing? Check out the best online tools for validating JSON syntax.
Working with multiple JSON files? The JSON merger tool combines them directly in your browser.
How JSON Works explains the format itself if you want to understand the specification.
JSON vs XML vs YAML compares the three data formats if you're choosing between them for a project.
Read More
All Articles
Best JSON Editor for Eclipse in 2026 (Plugins, Setup & Tips)
Looking for the best JSON editor for Eclipse? A rundown of the top Eclipse JSON plugins in 2026 including Wild Web Developer, JSON Editor Plugin, and more. Step-by-step setup, comparison tables, and real workflow tips for Java developers.

6 Best JSON Editors for Linux in 2026 (Free Tools, Ranked)
Looking for the best JSON editor for Linux? Explore 6 top free tools in 2026 including VS Code, Kate, Vim, Sublime Text, gedit, and jq. Comparison tables, honest reviews, and recommendations for every workflow.

8 Best Online Tools for Validating JSON Syntax in 2026
Need to check if your JSON is valid? These are the 8 best online JSON validators in 2026. Free tools that catch syntax errors, format messy JSON, and help you debug API responses without installing anything.