Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
Use Python’s built-in json module: json.loads() parses JSON text, json.load() reads JSON from a file-like object, json.dumps() turns a Python value into JSON text, and json.dump() writes JSON to a file-like object. The distinction is whether you have text or a stream, and whether you are reading or writing.
Choose the right JSON function
| Function | Direction | Input or output | Typical use |
|---|---|---|---|
json.loads() |
JSON to Python | JSON text as a string, bytes, or bytearray | Parse an API response body already held in memory |
json.load() |
JSON to Python | Readable file-like object | Read a JSON document from an open file |
json.dumps() |
Python to JSON | Python value in; JSON text string out | Build JSON text to send or store |
json.dump() |
Python to JSON | Python value in; writes text to a file-like object | Write a JSON document to an open file |
All four functions are in the standard-library json module, so there is no third-party package to install.
Parse JSON text with loads()
Use loads() when the JSON document is already a Python string, such as text read from a network response or assembled elsewhere.
import json
raw = '{"name": "Ada", "active": true, "scores": [9, 10], "nickname": null}'
record = json.loads(raw)
print(record["name"]) # Ada
print(record["active"]) # True
print(record["scores"]) # [9, 10]
print(record["nickname"]) # None
The argument must contain a complete JSON document. In JSON, strings and object keys use double quotes; Python-style single-quoted strings are not valid JSON. JSON’s true, false, and null become Python’s True, False, and None.
#1 Best Overall
Read a JSON file with load()
Use load() with an open text file. Open the file with an explicit encoding so the text is decoded consistently.
import json
with open("data.json", "r", encoding="utf-8") as file:
record = json.load(file)
print(record)
load() reads from a file-like object with a read() method. The same distinction applies to other readable streams: it is the stream, rather than a string containing JSON, that you pass to load().
Read bytes when necessary
loads() also accepts bytes and bytearray. For byte input, the JSON module supports UTF-8, UTF-16, and UTF-32. If you read a file as bytes yourself, use the expected encoding when decoding it, or pass the bytes directly to loads(). An incompatible byte encoding may raise UnicodeDecodeError, which is different from malformed JSON.
Quick wins for a faster PC:
Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Clear out junk files and repair common Windows errorsFree Scan →Scan for outdated or missing drivers - takes under a minuteDriver Scan →Write JSON text or a JSON file
Use dumps() when you need the encoded text as a Python string. Use dump() when you want to write to a text file or another file-like object whose write() method accepts strings.
Rank #2
import json
record = {"name": "Ada", "active": True, "scores": [9, 10], "nickname": None}
# Return JSON text as a Python str
text = json.dumps(record, indent=2)
print(text)
# Write one JSON document to a UTF-8 text file
with open("data.json", "w", encoding="utf-8") as file:
json.dump(record, file, indent=2)
Both examples produce valid JSON. The indented form is easier for people to inspect; compact output may be more convenient when you need a short string. dumps() returns a Python str, not bytes. If a later interface requires bytes, encode that string using the encoding expected by that interface.
Know which Python values JSON represents
Parsing converts JSON values to ordinary Python types. The default mapping is useful to know when accessing the result:
| JSON value | Python value |
|---|---|
| object | dict (with string keys) |
| array | list |
| string | str |
| number | int or float |
true / false |
True / False |
null |
None |
JSON does not define Python-specific values such as sets, dates, or arbitrary class instances. Before encoding one, choose a representation that your application and any receiving system understand—for example, a date string in a documented format—and convert it explicitly.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Format output and customize conversions
Make output readable or consistent
indent=2(or another indentation level) adds whitespace and line breaks for readability.sort_keys=Truewrites object keys in sorted order, which can help when comparing output or producing stable displays.ensure_ascii=Falseemits non-ASCII characters directly instead of escaping them. The result is still a Python string; choose the correct encoding when writing it.allow_nan=Falsemakes encoding rejectNaNand infinities instead of emitting those non-standard JSON values.
import json
record = {"city": "Zürich", "value": 12}
text = json.dumps(
record,
ensure_ascii=False,
sort_keys=True,
indent=2,
allow_nan=False,
)
print(text)
Convert unsupported values deliberately
Pass a default callable to dump() or dumps() when you want to define how otherwise unsupported values should be represented. Make the representation explicit rather than assuming JSON can preserve the original Python type.
import json
from datetime import date
def encode_special(value):
if isinstance(value, date):
return value.isoformat()
raise TypeError(f"Cannot serialize {type(value).__name__}")
text = json.dumps({"created": date(2026, 9, 29)}, default=encode_special)
print(text) # {"created": "2026-09-29"}
The receiving application gets a string; it does not automatically recover a date object. Define and apply a corresponding decoding rule if you need that conversion. Raising TypeError for unhandled types also prevents an accidental, misleading representation.
Customize decoding
Decoding hooks can change how values are constructed. For example, parse_float can preserve decimal precision by using decimal.Decimal, while object_hook can transform each decoded JSON object (dictionary) into an application-specific representation.
import json
from decimal import Decimal
value = json.loads('{"price": 0.10}', parse_float=Decimal)
print(value["price"]) # Decimal('0.10')
print(type(value["price"])) # <class 'decimal.Decimal'>
Choose hooks because the application needs their behavior, not just to make parsing succeed. For example, a Decimal value is not among the JSON module’s ordinary output types; if you later encode it, provide a deliberate conversion.
Handle malformed input and encoding errors
Malformed JSON raises json.JSONDecodeError, which is a ValueError subclass. Its line and column fields help locate the problem in the input.
import json
raw_text = '{"name": "Ada",}'
try:
data = json.loads(raw_text)
except json.JSONDecodeError as exc:
print(f"Invalid JSON at line {exc.lineno}, column {exc.colno}: {exc.msg}")
Catch this specific error when invalid external input is an expected possibility. Avoid replacing it with a blanket exception handler that hides unrelated programming or I/O failures.
Common causes and fixes
- Single quotes: JSON strings and keys require double quotes. Supply valid JSON rather than a Python representation such as
{'name': 'Ada'}. - Trailing comma: Remove the comma before a closing
}or]. - Missing separator or bracket: Check commas between members or array items and make sure every opening delimiter has a matching close.
- Empty or non-JSON response: Inspect the actual input before parsing. An empty response, an HTML error page, or other content is not a JSON document, even if it came from an endpoint you expected to return JSON.
UnicodeDecodeError: This points to byte decoding, not necessarily invalid JSON syntax. Check how bytes were encoded and read them as UTF-8, UTF-16, or UTF-32 as appropriate.- Wrong shape after parsing: A valid document can decode to a list, string, number, boolean, or
None, not just a dictionary. Check the structure before using dictionary indexing.
Avoid common writing and round-trip pitfalls
Do not concatenate independent documents with repeated dumps
JSON is not a framed protocol. Calling dump() repeatedly on the same file does not automatically add separators or create a valid sequence of independent JSON documents. For one JSON file, write one enclosing value—often a list—or define a separate line-oriented format and parse each line according to that format.
Dictionary keys may change in a round trip
JSON object keys are strings. When Python encodes a dictionary, non-string keys are coerced to strings. Consequently, json.loads(json.dumps(value)) is not guaranteed to equal value if it has non-string dictionary keys. Use string keys when the data is intended to round-trip through JSON without that change.
Recommended Free Tools
Reject non-standard numeric values when needed
Python can encounter values such as float("nan") or infinity. If the output must be strict JSON, set allow_nan=False so these values produce an error that you can handle, rather than emitting representations that are not standard JSON.
Best Value
Validate and pretty-print JSON from a terminal
To check JSON supplied on standard input and print it in a readable form, run:
python -m json < data.json
This is a quick syntax check and formatter for a document in a file. If the command reports an error, inspect the input around the reported location; the command does not turn Python literals into JSON or repair malformed input automatically.
Or skip the browser setup
If your workflow also needs a website screenshot, ScreenshotNeo provides a screenshot API; it is a separate task from parsing JSON with Python. One GET request can return a screenshot or PDF. The API response includes headers indicating the page verdict and whether the request was billed.
Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minutePC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
timeout=90,
)
open("shot.webp", "wb").write(r.content)
See the ScreenshotNeo API documentation for request parameters. Cookie banners, popups, and chat widgets are removed before the shot; bot checks, blank pages, and failed loads are never billed. An MCP server lets AI agents take screenshots. The Free plan includes 1,000 screenshots a month with no card, and paid plans start at $5 for 3,000. Learn about ScreenshotNeo or sign up for 1,000 free screenshots a month with no card.
Frequently Asked Questions
Can I parse JSON without installing a package?
Yes. Python’s standard-library json module is included with Python, so no separate JSON package is needed.
Does json.loads() accept a URL?
No. It accepts JSON text or bytes, not a URL. Retrieve the response body with an HTTP client first, then pass the response text or bytes to the JSON decoder.
Can I parse several JSON documents from one file with json.load()?
An ordinary JSON document contains one top-level value. A sequence of documents needs an explicitly defined framing convention; repeated dumps alone do not supply one.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

