Python JSONSchema Objects
python-jsonschema-objects is an active Python library (version 0.5.7) that provides automatic class-based binding to JSON Schemas, generating Python objects with built-in validation. It aims to reduce the tedium of writing object bindings for JSON schemas by auto-generating classes that seamlessly encode to and from JSON, complete with validations. The library has a moderate release cadence, with the last release in November 2024.
Common errors
-
ValidationError: -2 is less than 0
cause Attempting to assign a value that violates a `minimum` constraint defined in the JSON Schema.fixEnsure that assigned values adhere to all schema constraints, such as `minimum`, `maximum`, `minLength`, `maxLength`, etc. Example: `james.age = 5` instead of `james.age = -2`. -
ValidationError: ['Jasper', 'Spot', 'Noodles', 'Fido', 'Dumbo'] has too many elements. Wanted 4.
cause Attempting to assign an array with more items than allowed by the `maxItems` constraint defined in the JSON Schema.fixProvide an array with a number of elements within the bounds specified by `minItems` and `maxItems`. Example: `james.dogs = ['Jasper', 'Spot']`. -
AttributeError: 'Namespace' object has no attribute 'MySchema'
cause The generated class for your schema could not be found in the `Namespace` object returned by `builder.build_classes()`. This often happens if the schema's `title` field doesn't match the expected attribute name, or if `named_only=True` was used without a `title`.fixEnsure your schema has a `"title"` property (e.g., `"title": "MySchema"`) and access the generated class using `ns.MySchema`. Alternatively, iterate through `ns.__dict__` to see available generated classes.
Warnings
- gotcha The `jsonschema` library, a core dependency, has deprecated `jsonschema.RefResolver` in its v4.0.0+ releases in favor of the `referencing` library. `python-jsonschema-objects` still relies on `jsonschema.RefResolver`. This might lead to compatibility issues or unexpected behavior if a very recent `jsonschema` version is installed alongside `python-jsonschema-objects` or if `RefResolver`'s behavior changes significantly in future `jsonschema` updates.
- gotcha Regular expressions in JSON Schema (and thus in `python-jsonschema-objects`) are interpreted using Python's full regex engine, not just the subset allowed by the JSON Schema specification. This can lead to non-portable schemas or unexpected matches if patterns are not properly anchored with `^` (start) and `$` (end).
- gotcha By default, JSON Schemas often allow additional properties beyond those explicitly defined. If strictness is desired (i.e., disallowing any properties not defined in the schema), you must explicitly set `"additionalProperties": false` in your schema. Otherwise, `python-jsonschema-objects` will allow extra fields when deserializing or validating objects.
Install
-
pip install python-jsonschema-objects
Imports
- ObjectBuilder
from python_jsonschema_objects import ObjectBuilder
import python_jsonschema_objects as pjs builder = pjs.ObjectBuilder(schema)
Quickstart
import python_jsonschema_objects as pjs
import json
schema_str = '''
{
"title": "Example Schema",
"type": "object",
"properties": {
"firstName": {"type": "string"},
"lastName": {"type": "string"},
"age": {"description": "Age in years", "type": "integer", "minimum": 0},
"dogs": {"type": "array", "items": {"type": "string"}, "maxItems": 4}
},
"required": ["firstName", "lastName"]
}
'''
schema = json.loads(schema_str)
builder = pjs.ObjectBuilder(schema)
ns = builder.build_classes()
# Access the generated class by its title
Person = ns.ExampleSchema
# Create an instance and set properties
james = Person(firstName="James", lastName="Bond")
print(f"Created person: {james.firstName} {james.lastName}")
# Properties are validated on assignment
try:
james.age = -2
except pjs.ValidationError as e:
print(f"Validation error: {e.message}")
try:
james.dogs = ["Jasper", "Spot", "Noodles", "Fido", "Dumbo"]
except pjs.ValidationError as e:
print(f"Validation error: {e.message}")
# Serialize the object to JSON
json_output = james.serialize(sort_keys=True)
print(f"Serialized object: {json_output}")