Learn

Short lessons with real code you can edit and run on the page.

JSON in Python

Lesson 31 Python 3.14 Runs in your browser
In short

JSON is a text format for structured data, and Python's standard json module reads and writes it. json.loads() turns a JSON string into Python values such as dictionaries and lists, and json.dumps() turns Python values back into a JSON string.

Key facts

  • json.loads('{"a": 1}') returns the dictionary {'a': 1}.
  • json.dumps() writes True, False and None as true, false and null.
  • json.dump(data, f) writes JSON to an open file, and json.load(f) reads it back.
  • indent=2 puts each item on its own line, indented two spaces per level.
  • Text that json.loads() can't parse, such as {'a': 1} with single quotes, raises json.JSONDecodeError, which gives the line and column.

What is JSON in Python?

JSON is a text format for structured data, and the json module turns it into Python values. The module comes with Python, so import json is all the setup it needs.

Python
import json

text = '{"name": "Ada", "age": 36, "langs": ["en", "fr"]}'
data = json.loads(text)
print(data["name"], data["langs"][1])
print(type(data))
Output
Ada fr
<class 'dict'>

json.loads(), where the s stands for string, parsed the text. That means it read the JSON and built the matching Python value, here a dictionary. The key lookups from the dictionaries lesson work on it.

A JSON object is JSON's name for key-value pairs in curly braces, not an object made from a class. JSON objects become dictionaries, and JSON arrays, the values in square brackets, become lists.

Websites and apps exchange data as JSON, and config files often use it, because nearly every programming language can read and write it. The JSON to Python converter shows the Python version of any JSON you paste.

How do I convert Python data to a JSON string?

Pass the data to json.dumps(), and it returns a JSON string. Dictionaries, lists, tuples, strings, integers, floats, booleans and None all convert.

Python
import json

user = {"name": "Ada", "admin": True, "email": None, "tags": ("a", "b")}
print(json.dumps(user))
Output
{"name": "Ada", "admin": true, "email": null, "tags": ["a", "b"]}

The output uses JSON's spellings, so True became true and None became null, and every string is in double quotes. The tuple came out as a JSON array, the same as a list would, because JSON has no tuple type.

Turning Python data into JSON text is called serializing, and reading it back, as json.loads() does, is called deserializing.

How do I pretty-print JSON in Python?

Pass indent to json.dumps(), and each item goes on its own line. Adding sort_keys=True also puts the keys in order.

Python
import json

user = {"name": "Ada", "age": 36}
print(json.dumps(user, indent=2, sort_keys=True))
Output
{
  "age": 36,
  "name": "Ada"
}

indent=2 indents each level by two spaces, and indent=4 by four. sort_keys sorts by character code, not alphabetically, so "B" comes before "a" and "10" comes before "9".

How do I write a JSON file in Python?

Open the file for writing and pass it to json.dump() along with the data. dump(), without the s, writes straight to the file instead of returning a string.

Python
import json

settings = {"theme": "dark", "font_size": 14}

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

with open("settings.json", encoding="utf-8") as f:
    print(f.read())
Output
{
  "theme": "dark",
  "font_size": 14
}

Open JSON files with encoding="utf-8" too. The JSON standard requires UTF-8 for data shared between systems, and the files lesson explains why text files need an encoding.

Python 3.14 added python -m json for checking a JSON file from a terminal. It prints the file formatted or reports the first error, and older versions use python -m json.tool instead.

Terminal
python -m json settings.json

Run the command on your own computer in the folder that holds the file, with your file's name in place of settings.json. On macOS and Linux, type python3 instead of python.

How do I read a JSON file in Python?

Open the file and pass it to json.load(), which returns the parsed data. For a JSON object, that's a dictionary you can loop over and look up like any other.

Python
import json

with open("scores.json", "w", encoding="utf-8") as f:
    f.write('{"Ada": 90, "Grace": 85}')

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

for name, score in scores.items():
    print(name, score)
Output
Ada 90
Grace 85

Writing scores.json first lets the code run on its own. With a file that already exists, the with block that calls json.load() is all you need.

What is the difference between json.load() and json.loads()?

json.load() reads JSON from a file, and json.loads() reads it from a string. The same pattern separates dump(), which writes to a file, from dumps(), which returns a string.

The four json functions in Python
FunctionConvertsTakesGives back
json.loads(text)JSON to PythonA stringPython data
json.load(f)JSON to PythonAn open filePython data
json.dumps(data)Python to JSONPython dataA string
json.dump(data, f)Python to JSONPython data and an open fileNone, after writing to the file

Use the string versions for JSON that arrives as text, such as a website's response, and the file versions for files on disk. json.load(f) does the same job as json.loads(f.read()).

How do JSON types map to Python types?

JSON objects load as dict, arrays as list, strings as str, booleans as bool and null as None. Numbers load as int or float, and json.dumps() converts the same way in the other direction.

JSON types and the Python types they load as
JSONExamplePython type
Object{"a": 1}dict
Array[1, 2]list
String"hi"str
Whole number42int
Number with a decimal point or exponent4.5float
true and falsetruebool
nullnullNone

Two conversions don't survive a round trip. Tuples come back as lists, and keys that are numbers, booleans or None become strings, so the key 1 turns into '1'.

What causes a JSONDecodeError in Python?

json.loads() raises json.JSONDecodeError when it can't parse the text as JSON. Its message names the problem and gives the line and column where reading stopped.

Python
import json

bad = "{'name': 'Ada'}"
try:
    json.loads(bad)
except json.JSONDecodeError as e:
    print("Invalid JSON:", e)
Output
Invalid JSON: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)

JSON is stricter than Python. Keys and strings need double quotes, comments aren't allowed, and a comma after the last item is an error that Python 3.14 and 3.15 report as Illegal trailing comma before end of object (or array).

An empty string gives Expecting value: line 1 column 1 (char 0), and so does HTML that starts with <, such as a web server's error page. The JSON validator checks any JSON you paste and points at the first problem.

JSONDecodeError is a subclass of ValueError, so except ValueError catches it too. A traceback shows its full name, json.decoder.JSONDecodeError, which is the same class.

What does "not JSON serializable" mean in Python?

A value is not JSON serializable when the json module can't convert its type, such as a set. json.dumps() raises a TypeError for it, so convert a set to a list first, with sorted() if you want the items in a fixed order.

Python
import json

data = {"tags": {"python", "json"}}
try:
    json.dumps(data)
except TypeError as e:
    print(e)

print(json.dumps({"tags": sorted(data["tags"])}))
Output
Object of type set is not JSON serializable
{"tags": ["json", "python"]}

The same error appears for dates and for objects of your own classes. Turn them into strings, numbers, lists or dictionaries first, or pass default=str, which makes dumps() call str() on any value it can't convert.

Common mistakes with JSON in Python

Most of these four JSON mistakes in Python come from mixing up JSON text and the Python data it describes.

  • TypeError: string indices must be integers, not 'str'. JSON text is still a string until you parse it, so text["name"] fails. Call json.loads() first.
  • json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes. Single quotes around a key cause it. Single quotes around a value, or Python's True or None, give Expecting value instead. Write JSON with double quotes, true and null.
  • AttributeError: 'str' object has no attribute 'read'. json.load("settings.json") got a file name, but it expects an open file. Open the file with open() and pass the file object.
  • KeyError: 1. A dictionary key 1 comes back from JSON as the string '1', so data[1] finds nothing. Look up the string key, or convert the keys back with int() after loading.

The program below reads a key from the JSON text before parsing it. Change text["name"] to json.loads(text)["name"] and run it again.

Python
import json

text = '{"name": "Ada"}'
print(text["name"])
Output
Traceback (most recent call last):
  File "main.py", line 4, in <module>
    print(text["name"])
          ~~~~^^^^^^^^
TypeError: string indices must be integers, not 'str'

Exercise

Parse order into a new variable with json.loads(), add a "total" key for price times quantity, and print it with json.dumps(), so the output is the order with "total": 10.0 added at the end. The starter stops with a TypeError, because order is still a string.

Python
import json

order = '{"item": "pen", "price": 2.5, "quantity": 4}'
order["total"] = order["price"] * order["quantity"]
print(json.dumps(order))
Output
Show the solution
import json

order = '{"item": "pen", "price": 2.5, "quantity": 4}'
data = json.loads(order)
data["total"] = data["price"] * data["quantity"]
print(json.dumps(data))

Quiz

This quiz has 5 questions. Pick an answer to see why it is right or wrong.

  1. 1What does this program print?

    import json
    
    print(json.dumps({"ok": True, "note": None}))
  2. 2What does this program print?

    import json
    
    print(type(json.loads("[1, 2, 3]")).__name__)
  3. 3Which function writes JSON straight into an open file?

  4. 4What does this program print?

    import json
    
    data = json.loads(json.dumps({1: "one"}))
    print(data)
  5. 5Which of these strings is valid JSON?

Frequently asked questions

Is JSON built into Python?
Yes. The json module is part of the standard library, so import json works in any Python installation with no pip install.
What is the difference between json.dump() and json.dumps()?
json.dumps() returns the JSON as a string, and json.dump() writes it to a file object you pass in. Both take the same options, such as indent and sort_keys.
How do I get a value from JSON in Python?
Parse the JSON first, then look the value up by key or index. Use json.loads() for a string or json.load() for a file, and chain the lookups for nested values, as in data['user']['langs'][0].
Does json.dumps() keep the order of keys?
Yes. json.dumps() writes the keys in the order the dictionary holds them, which is the order they were added, and json.loads() keeps the order of the JSON text. Pass sort_keys=True to sort them instead.
Why are my integer keys strings after loading JSON in Python?
JSON allows only strings as object keys, so a number key such as 1 comes back as '1'. Convert the keys back with int() if your code needs numbers.
Why does json.dumps() turn é into \u00e9?
By default, json.dumps() escapes every character outside ASCII, so é becomes the six characters \u00e9. ASCII covers only basic English letters, digits and symbols. Pass ensure_ascii=False to keep real characters, and write the file with encoding='utf-8'.
How do I validate JSON from the command line with Python?
Run python -m json data.json on Python 3.14 or later, or python -m json.tool data.json on older versions. It prints the JSON formatted when it can parse the file, and the first error with its line and column when it can't.