Skip to content

Commit

Permalink
Merge pull request #295 from python-jsonschema/add-remote-yaml-support
Browse files Browse the repository at this point in the history
Add support for remote YAML/TOML/JSON5 schemas
  • Loading branch information
sirosen authored Aug 8, 2023
2 parents 76b19fe + da3a6af commit 2d6f144
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 15 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ Unreleased
non-JSON format supported by `check-jsonschema`. The file type is inferred
only from the file extension in these cases and defaults to JSON if there is
no recognizable extension.
- Remote schemafiles (http/s) now support YAML, TOML, and JSON5 formats, if the
URL ends with the appropriate extension and the matching parser is available.
Extensionless URLs are treated as JSON.

0.23.3
------
Expand Down
2 changes: 1 addition & 1 deletion src/check_jsonschema/checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ def _fail(self, msg: str, err: Exception | None = None) -> t.NoReturn:

def get_validator(
self, path: pathlib.Path, doc: dict[str, t.Any]
) -> jsonschema.Validator:
) -> jsonschema.protocols.Validator:
try:
return self._schema_loader.get_validator(
path, doc, self._format_opts, self._fill_defaults
Expand Down
10 changes: 5 additions & 5 deletions src/check_jsonschema/schema_loader/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@


def _extend_with_default(
validator_class: type[jsonschema.Validator],
validator_class: type[jsonschema.protocols.Validator],
) -> type[jsonschema.Validator]:
validate_properties = validator_class.VALIDATORS["properties"]

Expand Down Expand Up @@ -51,7 +51,7 @@ def get_validator(
instance_doc: dict[str, t.Any],
format_opts: FormatOptions,
fill_defaults: bool,
) -> jsonschema.Validator:
) -> jsonschema.protocols.Validator:
raise NotImplementedError


Expand Down Expand Up @@ -112,7 +112,7 @@ def get_validator(
instance_doc: dict[str, t.Any],
format_opts: FormatOptions,
fill_defaults: bool,
) -> jsonschema.Validator:
) -> jsonschema.protocols.Validator:
retrieval_uri = self.get_schema_retrieval_uri()
schema = self.get_schema()

Expand Down Expand Up @@ -141,7 +141,7 @@ def get_validator(
registry=reference_registry,
format_checker=format_checker,
)
return t.cast(jsonschema.Validator, validator)
return t.cast(jsonschema.protocols.Validator, validator)


class BuiltinSchemaLoader(SchemaLoader):
Expand All @@ -163,7 +163,7 @@ def get_validator(
instance_doc: dict[str, t.Any],
format_opts: FormatOptions,
fill_defaults: bool,
) -> jsonschema.Validator:
) -> jsonschema.protocols.Validator:
schema_validator = jsonschema.validators.validator_for(instance_doc)
meta_validator_class = jsonschema.validators.validator_for(
schema_validator.META_SCHEMA, default=schema_validator
Expand Down
15 changes: 12 additions & 3 deletions src/check_jsonschema/schema_loader/readers.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from __future__ import annotations

import json
import io
import typing as t

import ruamel.yaml
Expand Down Expand Up @@ -48,19 +48,28 @@ def __init__(
disable_cache: bool,
) -> None:
self.url = url
self.parsers = ParserSet()
self.downloader = CacheDownloader(
url,
cache_filename,
disable_cache=disable_cache,
validation_callback=json.loads,
validation_callback=self._parse,
)
self._parsed_schema: t.Any | None = None

def _parse(self, schema_bytes: bytes) -> t.Any:
if self._parsed_schema is None:
self._parsed_schema = self.parsers.parse_data_with_path(
io.BytesIO(schema_bytes), self.url, default_filetype="json"
)
return self._parsed_schema

def get_retrieval_uri(self) -> str:
return self.url

def _read_impl(self) -> t.Any:
with self.downloader.open() as fp:
return json.load(fp)
return self._parse(fp.read())

def read_schema(self) -> dict:
return _run_load_callback(self.url, self._read_impl)
19 changes: 13 additions & 6 deletions tests/unit/test_schema_loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import pathlib

import pytest
import responses

from check_jsonschema.schema_loader import SchemaLoader, SchemaParseError
from check_jsonschema.schema_loader.readers import HttpSchemaReader, LocalSchemaReader
Expand Down Expand Up @@ -40,12 +41,12 @@ def test_schemaloader_path_handling_relative_local_path(in_tmp_dir, filename):
[
"schema.yaml",
"schema.yml",
"https://foo.example.com/schema.yaml",
"https://foo.example.com/schema.yml",
],
)
def test_schemaloader_local_yaml_data(tmp_path, filename):
f = tmp_path / filename
f.write_text(
"""
def test_schemaloader_yaml_data(tmp_path, filename):
schema_text = """
---
"$schema": https://json-schema.org/draft/2020-12/schema
type: object
Expand All @@ -60,8 +61,14 @@ def test_schemaloader_local_yaml_data(tmp_path, filename):
c:
type: string
"""
)
sl = SchemaLoader(str(f))
if filename.startswith("http"):
responses.add("GET", filename, body=schema_text)
path = filename
else:
f = tmp_path / filename
f.write_text(schema_text)
path = str(f)
sl = SchemaLoader(path)
schema = sl.get_schema()
assert schema == {
"$schema": "https://json-schema.org/draft/2020-12/schema",
Expand Down

0 comments on commit 2d6f144

Please sign in to comment.