Python 3.15 json array_hook: freeze a Sume job result
Python 3.15 adds array_hook to json.load and json.loads. Pair it with frozendict to hold a completed Sume job result as deeply immutable data you can share.

To hold a completed Sume job result as deeply immutable data in Python 3.15, call json.loads with object_pairs_hook=frozendict and array_hook=tuple. The release notes describe exactly that combination as yielding a deeply nested immutable structure, and a completed Sume job's result.artifacts list is the kind of value you want to cache by job id and share across threads without a copy.
The language facts are from the What's New in Python 3.15 page, read 2026-10-03 while it was a release candidate; the result shape is from Jobs and results. I did not execute this on a 3.15 build, so test it before you ship it.
What does array_hook do?
The release notes say array_hook is a new parameter of json.load and json.loads: a callback that receives each JSON array so you can build something other than a list. Passing the built-in frozendict to object_pairs_hook and tuple to array_hook gives an immutable representation of the whole document, objects as frozen mappings and arrays as tuples.
What does a Sume result look like?
A completed job carries id, status: "completed" and result.artifacts, a list of objects with id, url, type and content_type. Artifact URLs are Sume media URLs; raw provider URLs are not public API outputs. Fetch the result only after result_ready is true or status is completed, because GET /v1/jobs/:id/result on an unfinished job answers 409 job_not_completed.
Sume's docs describe a result as available only after completion, so cache only terminal jobs, keyed by job id, and never cache a queued or processing read: those are normal non-terminal states.
| JSON field | Type after the hooks | Note |
|---|---|---|
id | str | The job id; use it as the cache key |
status | str | Only cache when completed |
result | frozendict | Present on completed jobs |
result.artifacts | tuple of frozendict | Order is preserved |
artifacts[].url | str | A Sume media URL, not a provider URL |
artifacts[].content_type | str | For example image/png |
Sources
Related posts
More in Developers
- Python 3.15 lazy import in a Sume webhook handler: what to defer
Python 3.15 adds the lazy import keyword. In a Sume webhook receiver with a 10-second attempt budget, defer only the modules the signature check does not need.
- Python 3.15 UTF-8 default: still verify Sume webhooks on raw bytes
Python 3.15 makes UTF-8 the default for open() without an encoding. It does not change that a Sume signature covers raw body bytes, so verify before any parse.
- Python: list Sume video models that accept a video input
A 20-line Python script reads GET /v1/videos/models and prints every model whose supported_input_references include video_url, with its duration range.
- Python match on a Sume run status: terminal is not success
A Format run can be terminal as completed, failed, canceled or skipped. A structural match that never treats done as success, with a null-output case.
Written by Sume