Open
Description
I have a schema that heavily utilises $dynamicRef
to inject parts of schema from other files.
Namely, here is the base schema:
base.json
:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "base.json",
"type": "object",
"additionalProperties": false,
"properties": {
"orderNumber": {
"type": "integer",
"minimum": 0
},
"downstreamNumber": {
"$dynamicRef": "#specialDownstreamNumber"
},
"schemaName": {
"$dynamicRef": "#concreteName"
},
"schemaVersion": {
"$dynamicRef": "#concreteVersion"
},
"timestamp": {
"type": "integer"
},
"data": {
"$dynamicRef": "#concreteData"
}
},
"required": [
"data",
"orderNumber",
"schemaName",
"schemaVersion",
"downstreamNumber",
"timestamp"
],
"$defs": {
"name": {
"const": "base",
"$dynamicAnchor": "concreteName"
},
"version": {
"const": "0.0.0",
"$dynamicAnchor": "concreteVersion"
},
"data": {
"not": true,
"$dynamicAnchor": "concreteData"
},
"downstreamNumber": {
"type": "integer",
"minimum": 1,
"$dynamicAnchor": "specialDownstreamNumber"
}
}
}
And here is the specific JSON that fills in the data for the base:
camera.json
:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "camera.json",
"$ref": "base.json",
"$defs": {
"name": {
"const": "camera.info",
"$dynamicAnchor": "concreteName"
},
"version": {
"const": "1.0.0",
"$dynamicAnchor": "concreteVersion"
},
"data": {
"$dynamicAnchor": "concreteData",
"type": "object",
"additionalProperties": false,
"properties": {
"cameraFacing": {
"enum": [
"Front",
"Back"
]
},
"cameraFrameSize": {
"$ref": "#/$defs/size"
},
"roi": {
"$ref": "#/$defs/size"
},
"viewPortAspectRatio": {
"type": "number"
}
},
"required": [
"cameraFacing",
"cameraFrameSize",
"roi",
"viewPortAspectRatio"
]
},
"downstreamNumber": {
"type": "integer",
"minimum": 0,
"$dynamicAnchor": "specialDownstreamNumber"
},
"size": {
"type": "object",
"additionalProperties": false,
"properties": {
"width": {
"type": "integer"
},
"height": {
"type": "integer"
}
},
"required": [
"width",
"height"
]
}
}
}
Here is the JSON that I'm trying to validate:
{
"orderNumber": 4,
"downstreamNumber": 1,
"schemaVersion": "1.0.0",
"schemaName": "camera.info",
"timestamp": 1756525700,
"data": {
"cameraFacing": "Back",
"cameraFrameSize": {
"width": 3841,
"height": 2161
},
"roi": {
"width": 3840,
"height": 1858
},
"viewPortAspectRatio": 2.066
}
}
Here is how I'm doing the validation:
import json
from pathlib import Path
from jsonschema.validators import Draft202012Validator
from referencing import Registry, Resource
ROOT = Path(__file__).absolute().parent
SCHEMAS = ROOT / Path("schema")
def validate_file(validator: Draft202012Validator, file: Path):
with open(file, "rt", encoding="utf-8") as f:
instance = json.load(f)
instance = json.loads(file.read_text())
print(f"Validating {file}...")
validator.validate(instance)
def retrieve_from_filesystem(uri: str):
path = SCHEMAS / Path(uri)
contents = json.loads(path.read_text())
return Resource.from_contents(contents)
def main():
registry = Registry(retrieve=retrieve_from_filesystem)
schema_file = SCHEMAS / Path("camera.json")
with open(schema_file, "rt", encoding="utf-8") as f:
schema = json.load(f)
validator = Draft202012Validator(
schema,
registry=registry
)
tests_path = ROOT / Path("payload")
for file in tests_path.iterdir():
validate_file(validator, file)
if __name__ == "__main__":
main()
The validation fails with exception:
jsonschema.exceptions._WrappedReferencingError: PointerToNowhere: '/$defs/size' does not exist within {'$schema': 'https://json-schema.org/draft/2020-12/schema', '$id': 'base.json', 'type': 'object', 'additionalProperties': False, 'properties': {'orderNumber': {'type': 'integer', 'minimum': 0}, 'downstreamNumber': {'$dynamicRef': '#specialDownstreamNumber'}, 'schemaName': {'$dynamicRef': '#concreteName'}, 'schemaVersion': {'$dynamicRef': '#concreteVersion'}, 'timestamp': {'type': 'integer'}, 'data': {'$dynamicRef': '#concreteData'}}, 'required': ['data', 'orderNumber', 'schemaName', 'schemaVersion', 'downstreamNumber', 'timestamp'], '$defs': {'name': {'const': 'base', '$dynamicAnchor': 'concreteName'}, 'version': {'const': '0.0.0', '$dynamicAnchor': 'concreteVersion'}, 'data': {'not': True, '$dynamicAnchor': 'concreteData'}, 'downstreamNumber': {'type': 'integer', 'minimum': 1, '$dynamicAnchor': 'specialDownstreamNumber'}}}
Which is incorrect, as camera.json
does contain /$defs/size
. I've tried validating the payload with a different validator and it validates the payload successfully.
I don't see anything wrong with my schema definitions and boon has no problem validating the payload.
Is this a bug in jsonschema
library or did I do something wrong and boon
fails to detect it?
Metadata
Metadata
Assignees
Labels
No labels