Batu Lab NotesPractical developer guides

Keep a JSON schema-like required-field check small

By Batu · English technical notes

Also published in our primary archive.

To keep a JSON schema-like required-field check small in Python, decode the object, then subtract its keys from the short set of required names. For the question “python keep a JSON schema-like required-field check small,” that gives a direct answer when the contract is only id and status.

The failing JSON text is {"id":"A"}. json.loads accepts it and produces {'id': 'A'}: the input is valid JSON, but it does not satisfy this application-level presence rule. The first call to check_required therefore returns ['status']. This separates decoding from validation without claiming that a generic schema framework was attempted or failed.

The corrected JSON text adds the required name: {"id":"A","status":"ready"}. It decodes to a dictionary whose keys satisfy the same set difference, so the second result is an empty list. Sorting the difference makes a multi-field report deterministic; here it also makes the expected one-field report explicit. The assertions check both decoded values and both validation outcomes.

The standard-library json documentation specifies that JSON objects decode to Python dict values and documents json.loads. This presence-only check does not validate value types, reject unexpected keys, validate nested objects, apply defaults, or produce path-specific errors. Add those rules only if the contract needs them. This example uses Python 3.0+.

AI assistance disclosure: this article was prepared with AI assistance.

Example

import json


def check_required(value, required):
    return sorted(required - value.keys())


required = {"id", "status"}
failing_text = '{"id":"A"}'
corrected_text = '{"id":"A","status":"ready"}'

failing_value = json.loads(failing_text)
failing_missing = check_required(failing_value, required)
corrected_value = json.loads(corrected_text)
corrected_missing = check_required(corrected_value, required)

assert failing_value == {"id": "A"}
assert failing_missing == ["status"]
assert corrected_value == {"id": "A", "status": "ready"}
assert corrected_missing == []

print("decoded failing value: {}".format(failing_value))
print("missing fields: {}".format(failing_missing))
print("decoded corrected value: {}".format(corrected_value))
print("missing fields: {}".format(corrected_missing))

Expected output:

decoded failing value: {'id': 'A'}
missing fields: ['status']
decoded corrected value: {'id': 'A', 'status': 'ready'}
missing fields: []