JSON Utilities API in Home Assistant Helpers: Complete Developer Guide
The JSON utilities API in Home Assistant helpers provides high-performance JSON serialization using orjson, custom encoders for Home Assistant objects, and robust error handling with diagnostic path mapping.
The home-assistant/core repository includes a comprehensive JSON utilities module located at homeassistant/helpers/json.py that standardizes how the platform serializes data to JSON. This API abstracts the complexity of encoding Home Assistant-specific objects while delivering superior performance through optimized libraries.
Core Components of the JSON Utilities API
High-Performance Encoding with orjson
The API leverages orjson for the majority of encoding operations because it is orders of magnitude faster than the standard library json module and natively supports dataclasses. The json_bytes function in homeassistant/helpers/json.py (lines 63-66) uses orjson.dumps with OPT_NON_STR_KEYS to handle non-string dictionary keys efficiently.
For deterministic output suitable for caching or hashing, json_dumps_sorted applies OPT_SORT_KEYS to guarantee consistent key ordering.
Custom JSON Encoders for Home Assistant Objects
The module provides multiple encoder strategies to handle Home Assistant's rich object ecosystem:
json_encoder_default(lines 38-55): A standalone default function used by orjson that handlesjson_fragment, collections,Pathobjects,datetimeinstances, and falls back toreprfor unknown types.JSONEncoder(lines 20-36): A subclass ofjson.JSONEncoderthat recognizes objects exposingas_dictmethods, plus native handling fordatetime,set, and other common types.ExtendedJSONEncoder(lines 70-88): ExtendsJSONEncoderto additionally serializedatetime.timedelta,date,time, and provides a saferepr-based dictionary for completely unknown types.
Error Handling and Serialization Diagnostics
When serialization fails, the API provides robust diagnostics through prepare_save_json (lines 63-78). This function captures TypeError exceptions from the encoder and invokes find_paths_unserializable_data (lines 18-68) to walk the data structure and locate the exact path of the offending element. It then raises a SerializationError (defined in homeassistant/util/json.py) with a human-readable path description.
Persistence and File Operations
The save_json function (lines 99-116) provides a high-level interface for writing JSON to disk. It handles mode selection (private files vs. world-readable), atomic writes via write_utf8_file_atomic, and integrates with the error handling pipeline. This ensures that configuration files and state storage are written safely without corruption risks.
Key Functions and Classes
The JSON utilities API exposes the following primary symbols:
json_bytes(data): Fast binary dump via orjson withOPT_NON_STR_KEYS.json_dumps(data): Returns a UTF-8 string by decodingjson_bytes.json_dumps_sorted(data): Deterministic JSON string with sorted keys.json_bytes_strip_null(data): Removes embedded NUL characters (\u0000) before dumping.save_json(filename, data, private=False, encoder=None, atomic_writes=False): High-level file persistence with atomic write support.prepare_save_json(data, encoder=None): Returns a(mode, json_payload)tuple with error detection.find_paths_unserializable_data(bad_data, dump=json.dumps): Diagnostic walker to locate serialization failures.json_encoder_default(obj): Default callback for orjson handling Home Assistant objects.JSONEncoder: Standard library compatible encoder class.ExtendedJSONEncoder: Extended encoder with additional type support and safe fallbacks.
Practical Code Examples
Serializing a Custom Home Assistant Object
from datetime import datetime
from homeassistant.helpers.json import json_dumps, JSONEncoder
class MyEntity:
def __init__(self, name: str, when: datetime):
self.name = name
self.when = when
def as_dict(self):
# Home Assistant objects expose as_dict for JSONEncoder
return {"name": self.name, "when": self.when}
entity = MyEntity("sensor.foo", datetime.utcnow())
payload = json_dumps(entity) # uses JSONEncoder automatically
print(payload) # {"name":"sensor.foo","when":"2026-02-28T15:12:34.567890+00:00"}
Source: JSONEncoder implementation – homeassistant/helpers/json.py#L20-L36
Persisting a Configuration Dictionary Atomically
from homeassistant.helpers.json import save_json
config = {
"scan_interval": 30,
"devices": [{"id": "abc123", "enabled": True}]
}
# Write to a private file using an atomic rename to avoid corruption
save_json(
filename="/config/.storage/my_integration.json",
data=config,
private=True,
atomic_writes=True,
)
Source: save_json – homeassistant/helpers/json.py#L99-L116
Debugging a Serialization Error
from homeassistant.helpers.json import save_json, SerializationError
from homeassistant.helpers.json import find_paths_unserializable_data
bad_data = {"valid": 1, "bad": set([1, 2, 3])} # orjson cannot handle set without default
try:
save_json("bad.json", bad_data)
except SerializationError as err:
# Locate the offending path
paths = find_paths_unserializable_data(bad_data)
print("Unserializable locations:", paths)
Source: prepare_save_json error handling – homeassistant/helpers/json.py#L63-L78
Removing Stray NUL Characters
from homeassistant.helpers.json import json_bytes_strip_null
data = {"name": "sensor\0foo", "value": 42}
binary = json_bytes_strip_null(data) # NUL after "sensor" is stripped
print(binary.decode()) # {"name":"sensor","value":42}
Source: json_bytes_strip_null – homeassistant/helpers/json.py#L90-L112
Source File Reference
The JSON utilities API spans several key files in the home-assistant/core repository:
homeassistant/helpers/json.py: Central implementation containingJSONEncoder,json_bytes,save_json, and diagnostic functions.homeassistant/util/json.py: DefinesSerializationErrorandformat_unserializable_dataused by the helpers for error reporting.homeassistant/util/file.py: Provideswrite_utf8_fileandwrite_utf8_file_atomicused bysave_jsonfor safe disk writes.
Summary
- The JSON utilities API in Home Assistant helpers centralizes all JSON serialization logic in
homeassistant/helpers/json.py. - It uses orjson for high-performance encoding via
json_bytesandjson_dumps, falling back to custom encoders for complex objects. - Custom encoders (
JSONEncoder,ExtendedJSONEncoder,json_encoder_default) handle Home Assistant objects exposingas_dict,datetimeobjects,Pathobjects, and sets. - Robust error handling via
prepare_save_jsonandfind_paths_unserializable_dataprovides exact path diagnostics when serialization fails. - Safe persistence is handled by
save_json, which supports atomic writes and private file permissions to prevent data corruption.
Frequently Asked Questions
What makes the Home Assistant JSON utilities faster than standard Python json?
The API uses orjson for the majority of operations, which is implemented in Rust and provides significantly better performance than Python's standard library json module. Functions like json_bytes leverage orjson.dumps with OPT_NON_STR_KEYS to handle non-string dictionary keys efficiently, while json_dumps_sorted uses OPT_SORT_KEYS for deterministic output without the performance penalty of Python's sort_keys parameter.
How does the API handle custom Home Assistant objects that aren't standard JSON types?
The API provides multiple encoder strategies through json_encoder_default, JSONEncoder, and ExtendedJSONEncoder. These recognize objects that expose an as_dict method (common in Home Assistant entities), as well as native Python types like datetime, set, Path, and timedelta. When an object cannot be natively encoded, the extended encoder falls back to a safe repr-based representation rather than raising an exception immediately.
What should I do when save_json throws a SerializationError?
When save_json raises a SerializationError, use the find_paths_unserializable_data function to diagnose the issue. This function walks your data structure and returns the exact path to the offending element that cannot be serialized. For example, if you accidentally included a set or a custom object without an as_dict method, the diagnostic output will pinpoint the exact location in your dictionary or list structure, allowing you to fix the data before retrying the save operation.
Where are the JSON utility functions located in the Home Assistant codebase?
The primary implementation resides in homeassistant/helpers/json.py, which contains the encoder classes, dump functions, and persistence helpers. Supporting infrastructure includes homeassistant/util/json.py (which defines SerializationError and formatting utilities) and homeassistant/util/file.py (which provides atomic file write operations used by save_json). These files work together to provide the complete JSON serialization stack used throughout the Home Assistant core.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →