47 lines
1.4 KiB
Python
47 lines
1.4 KiB
Python
from json import loads
|
|
from urllib.parse import urlsplit
|
|
from urllib.request import urlopen
|
|
|
|
from referencing import Resource
|
|
from referencing import Specification
|
|
from referencing.typing import URI
|
|
from referencing.typing import Retrieve
|
|
|
|
from jsonschema_path.typing import ResolverHandlers
|
|
from jsonschema_path.typing import Schema
|
|
|
|
USE_REQUESTS = False
|
|
try:
|
|
import requests
|
|
except ImportError:
|
|
pass
|
|
else:
|
|
USE_REQUESTS = True
|
|
|
|
|
|
class SchemaRetriever(Retrieve[Schema]):
|
|
def __init__(
|
|
self, handlers: ResolverHandlers, specification: Specification[Schema]
|
|
):
|
|
self.handlers = handlers
|
|
self.specification = specification
|
|
|
|
def __call__(self, uri: URI) -> Resource[Schema]:
|
|
scheme = urlsplit(uri).scheme
|
|
if scheme in self.handlers:
|
|
handler = self.handlers[scheme]
|
|
contents = handler(uri)
|
|
return self.specification.create_resource(contents)
|
|
|
|
else:
|
|
if scheme in ["http", "https"] and USE_REQUESTS:
|
|
# Requests has support for detecting the correct encoding of
|
|
# json over http
|
|
contents = requests.get(uri).json()
|
|
return self.specification.create_resource(contents)
|
|
|
|
# Otherwise, pass off to urllib and assume utf-8
|
|
with urlopen(uri) as url:
|
|
contents = loads(url.read().decode("utf-8"))
|
|
return self.specification.create_resource(contents)
|