def resolve_ref(ref): file, path = urldefrag(ref) data = read_yaml(file) if len(path) > 0: for path in path.split('/'): data = data[int(path)] if path.isdigit() else data[path] return data
def resolving(self, ref): """ Context manager which resolves a JSON ``ref`` and enters the resolution scope of this ref. :argument str ref: reference to resolve """ full_uri = urljoin(self.resolution_scope, ref) uri, fragment = urldefrag(full_uri) if not uri: uri = self.base_uri if uri in self.store: document = self.store[uri] else: try: document = self.resolve_remote(uri) except Exception as exc: raise RefResolutionError(exc) old_base_uri, self.base_uri = self.base_uri, uri try: with self.in_scope(uri): yield self.resolve_fragment(document, fragment) finally: self.base_uri = old_base_uri
def parse_ref_url(self, ref): """Parse a reference URL into a tuple of base + parts. Schemas are renamed for easier processing. >>> r = RefRenamer({"file://base.json": "base"}) >>> sorted(r.items()) [('file://base.json', 'base')] >>> r.parse_ref_url("file://base.json") ('base',) >>> r.parse_ref_url("file://base.json#/foo/bar") ('base', 'foo', 'bar') >>> sorted(r.items()) [('file://base.json', 'base')] >>> r.parse_ref_url("file://other.json") ('schema0',) >>> r.parse_ref_url("file://other.json#/foo/bar") ('schema0', 'foo', 'bar') >>> sorted(r.items()) [('file://base.json', 'base'), ('file://other.json', 'schema0')] """ url, fragment = urldefrag(ref) try: rename = self.renames[url] except KeyError: self.renames[url] = rename = next(self.names) return (rename, ) + fragment_decode(fragment, prefix="")
def resolve_from_url(self, url): uri, ref = urldefrag(url) try: doc = self.store[uri] except KeyError: doc = self.resolve_remote(uri) if not re.search(self.root_scope, uri) else super().resolve_from_url(url) return self.resolve_fragment(doc, ref)
def resolve_from_url(self, url): url, fragment = urldefrag(url) try: document = self.store[url] except KeyError: try: document = self.resolve_remote(url) except Exception as exc: raise RefResolutionError(exc) return self.resolve_fragment(document, fragment)
def resolve(self, ref, document=None): """Resolve a fragment within the schema. If the resolved value contains a $ref, it will attempt to resolve that as well, until it gets something that is not a reference. Circular references will raise a SchemaError. :param str ref: URI to resolve. :param dict document: Optional schema in which to resolve the URI. :returns: a tuple of the final, resolved URI (after any recursion) and resolved value in the schema that the URI references. :raises SchemaError: """ try: # This logic is basically the RefResolver's resolve function, but # updated to support fragments of dynamic documents. The jsonschema # module supports passing documents when resolving fragments, but # it doesn't expose that capability in the resolve function. url = self._urljoin_cache(self.resolution_scope, ref) if document is None: # No document passed, so just resolve it as we normally would. resolved = self._remote_cache(url) else: # Document passed, so assume it's a fragment. _, fragment = urldefrag(url) resolved = self.resolve_fragment(document, fragment) except jsonschema.RefResolutionError as e: # Failed to find a ref. Make the error a bit prettier so we can # figure out where it came from. message = e.args[0] if self._scopes_stack: message = '{} (from {})'.format( message, self._format_stack(self._scopes_stack)) raise SchemaError(message) if isinstance(resolved, dict) and '$ref' in resolved: # Try to resolve the reference, so we can get the actual value we # want, instead of a useless dict with a $ref in it. if url in self._scopes_stack: # We've already tried to look up this URL, so this must # be a circular reference in the schema. raise SchemaError('Circular reference in schema: {}'.format( self._format_stack(self._scopes_stack + [url]))) try: self.push_scope(url) return self.resolve(resolved['$ref']) finally: self.pop_scope() else: return url, resolved
def resolve_from_url(self, uri): uri, fragment = urldefrag(uri) split_url = urlsplit(uri) if split_url.scheme in self.handlers: return self.handlers[split_url.scheme](uri) full_path = find_schema_path(uri.split('/')[-1]) if full_path: with open(full_path) as fp: json_schema = json.load(fp) if not json_schema: # TODO: fix exception method raise RefResolutionError("Unresolvable JSON schema: %r" % uri) return self.resolve_fragment(json_schema, fragment) else: # if a schema can't be found locally, just default to using the standard resolver return super(DjangoSchemaResolver, self).resolve_from_url(uri)
def base_uri(self): uri, _ = urldefrag(self.resolution_scope) return uri
def base_uri(self): """ Retrieve the current base URI, not including any fragment. """ uri, _ = urldefrag(self.resolution_scope) return uri