Skip to content

Commit b204d4c

Browse files
committed
feat: Allow schemas to reference other schemas
This allows us to reference external schemas to avoid duplication. They can be referenced like ``` "$ref": "file://uptime-results.v1.schema.json#/definitions/CheckResult" ``` The handler assumes all schemas will be located in out `schemas` directory.
1 parent 272c2ce commit b204d4c

File tree

3 files changed

+24
-4
lines changed

3 files changed

+24
-4
lines changed

python/sentry_kafka_schemas/codecs/json.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from __future__ import annotations
22

3+
import pathlib
34
from typing import Any, Optional, TypeVar, cast
45

56
import fastjsonschema
@@ -8,14 +9,24 @@
89

910
T = TypeVar("T")
1011

12+
BASE_DIR = pathlib.Path(__file__).parent.parent / "schemas"
13+
14+
15+
def file_handler(uri):
16+
absolute_path = BASE_DIR / uri[7:]
17+
if not absolute_path.exists():
18+
raise FileNotFoundError(f"Schema file not found: {absolute_path}")
19+
with open(absolute_path) as f:
20+
return rapidjson.load(f)
21+
1122

1223
class JsonCodec(Codec[T]):
1324
def __init__(
1425
self,
1526
json_schema: Optional[object],
1627
) -> None:
1728
if json_schema is not None:
18-
self.__validate = fastjsonschema.compile(json_schema)
29+
self.__validate = fastjsonschema.compile(json_schema, handlers={"file": file_handler})
1930
else:
2031
self.__validate = lambda _: None
2132

python/sentry_kafka_schemas/codecs/msgpack.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import fastjsonschema
44
import msgpack
55
from sentry_kafka_schemas.codecs import Codec, ValidationError
6+
from sentry_kafka_schemas.codecs.json import file_handler
67

78
T = TypeVar("T")
89

@@ -14,7 +15,7 @@ class MsgpackCodec(Codec[T]):
1415

1516
def __init__(self, json_schema: Optional[object]) -> None:
1617
if json_schema is not None:
17-
self.__validate = fastjsonschema.compile(json_schema)
18+
self.__validate = fastjsonschema.compile(json_schema, handlers={"file": file_handler})
1819
else:
1920
self.__validate = lambda _: None
2021

python/tests/test_examples.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@
55
import pytest
66
import rapidjson
77
from sentry_kafka_schemas import iter_examples
8+
from sentry_kafka_schemas.codecs.json import file_handler, BASE_DIR
89
from sentry_kafka_schemas.sentry_kafka_schemas import _get_schema, get_codec, get_topic, list_topics
910
from sentry_kafka_schemas.types import Example
11+
from jsonschema import RefResolver
1012

1113

1214
def get_all_examples() -> Iterator[Tuple[str, int, Example]]:
@@ -65,11 +67,17 @@ def test_json_examples(
6567
example_data = example.load()
6668

6769
if jsonschema_library == "fastjsonschema":
68-
compiled = fastjsonschema.compile(schema)
70+
compiled = fastjsonschema.compile(schema, handlers={"file": file_handler})
6971
compiled(example_data)
7072
elif jsonschema_library == "jsonschema":
7173
try:
72-
jsonschema.validate(example_data, schema)
74+
#TODO: Is this even necessary? Looks like we removed usage of jsonschema?
75+
resolver = RefResolver(
76+
base_uri=f"file:/{BASE_DIR}",
77+
referrer=schema,
78+
handlers={"file": file_handler} # Use the custom_resolver function
79+
)
80+
jsonschema.validate(example_data, schema, resolver=resolver)
7381
except jsonschema.ValidationError as e:
7482
_get_most_specific_jsonschema_error(e)
7583
elif jsonschema_library == "rapidjson":

0 commit comments

Comments
 (0)