jschon.resource

exception jschon.resource.DuplicateResourceURIError

Raised if an empty relative URI is used for a resource root, which produces a duplicate URI of the resource that provided the initial base URI.

exception jschon.resource.InconsistentResourceRootError

Raised when resource_root and is_resource_root() disagree during instantiation.

exception jschon.resource.RelativeResourceURIError

Raised when attempting to set a URI to a relative URI-reference without an available base URI.

exception jschon.resource.ResourceError

An error originating in the resource module.

exception jschon.resource.ResourceNotReadyError

Raised if the path, parent, and resource_root attributes are not availalbe on resource initialization.

exception jschon.resource.ResourceURINotSetError

Raised when accessing any URI property before the URI has been set.

exception jschon.resource.UnRootedResourceError

Raised when there is no JSONResource root in the resource.

This can happen if neither the current node nor any of its ancestors are explicitly marked as resoruce roots in some way, and the document root node, which is the default resource root, is not a JSONResource instance.

class jschon.resource.JSONResource(value, *, parent=None, key=None, catalog='catalog', cacheid='default', uri=None, initial_base_uri=None, default_uri_factory=<function <lambda>>, additional_uris=frozenset({}), resolve_references=True, pre_recursion_args=None, itemclass=None, **itemkwargs)

Supports URIs and Catalog management.

This class faciliates the extension of jschon to formats beyond JSON Schema, and is not intended for direct use. JSON subclasses representing document nodes in a URI-identified resource should inherit from this class, which overrides jschon.json.JSON.pre_recursion_init() to set up the resource infrastructure.

.

JSON subclasses that can contain references among or within documents must implement resolve_references().

Resources have at least one URI and can serve as reference sources and / or targets. They can be loaded by requesting them by URI from a Catalog instance, which is the typical way to resolve references from one resource to another.

In some document formats, only certain nodes are relevant to resource identity. This class supports the notion of a parent-in-resource, which is the nearest parent node that might impact resource identity. It also supports the determination of a resource root other than the document root.

For example, in JSON Schema documents, only schema nodes can determine resource identity, and only the “$id” keyword indicates a resource root other than the document root.

A resource can encompass multiple formats, such as in OpenAPI 3.1 where a Schema Object is a JSON Schema-format structure, but is not a distinct resource from the OpenAPI document unless it contains “$id”.

All constructor parameters are either passed through directly to jschon.json.JSON.__init__() or are passed via its pre_recursion_args parameter to :meth:pre_recursion_init`; see those methods for parameter documentation. The one exception is pre_recursion_args itself, which is merged with but in cases of conflict takes precedence over the pre-recursion arguments produced by this class.

__init__(value, *, parent=None, key=None, catalog='catalog', cacheid='default', uri=None, initial_base_uri=None, default_uri_factory=<function <lambda>>, additional_uris=frozenset({}), resolve_references=True, pre_recursion_args=None, itemclass=None, **itemkwargs)
Parameters:
  • value (JSONCompatible) –

  • parent (JSON) –

  • key (str) –

  • catalog (Union[str, Catalog]) –

  • cacheid (Hashable) –

  • uri (Optional[URI]) –

  • initial_base_uri (Optional[URI]) –

  • default_uri_factory (Callable[[], URI]) –

  • additional_uris (Set[URI]) –

  • resolve_references (bool) –

  • pre_recursion_args (Optional[Dict[str, Any]]) –

  • itemclass (Type[JSON]) –

  • itemkwargs (Any) –

Return type:

None

is_resource_root()

True if this node is at the root of a distinct resource.

This base class defines resource_root-ness to be equivalent to document_root. Resources that can have non-document-root resource roots must subclass and override this method.

The document root should always be considered a resource root.

Return type:

bool

pre_recursion_init(*, catalog='catalog', cacheid='default', uri=None, additional_uris=frozenset({}), initial_base_uri=None, default_uri_factory=<function <lambda>>, resolve_references=True, **kwargs)

Configure identifiers and register with the catalog if needed.

This method is intended to be called by __init__() methods only.

The resource is registered under the following conditions:

  • uri does not have a fragment

  • uri has an empty fragment, which is interpreted as a root JSON Pointer; the resource is then registered under the semantically equivalent absolute-URI (as defiend by RFC 3986 §4.3)

  • uri has a non-JSON Pointer fragment
    • If also a resource root, the absolute-URI form is also registered

  • uri is None and this node is a resource root, in which case

a UUID URN is generated and registered

The Catalog can resolve JSON Pointer fragment URIs without cluttering the cache with them. The empty JSON Pointer fragment is special-cased due to its complex history in JSON Schema’s "$id" keyword.

Parameters:
  • uri (Optional[URI]) – The URI under which this document is to be registered with the Catalog, which may be adjusted as explaine above. If created by the catalog, this will be the URI used to request the resource.

  • catalog (Union[Catalog, str]) – The catalog name or instance managing this resource.

  • cacheid (Hashable) – The identifier for the cache within the catalog in which this resource is stored.

  • uri – The primary URI initially used to identify the resource. This is handled and, if appropriate, registered with the relevant Catalog, as documented above. If it differs from a relative URI specified in the content, and if no initial_base_uri parameter is provided, it is treated as the retrieval URI in accordance with RFC 3986 §5.1.3, as that is how the Catalog sets it when instantiating a resource retrieved from storage.

  • additional_uris (Set[URI]) – Additional URIs under which this resource should be registered. The caller is responsible for ensuring that these URIs, along with the uri parameter, do not conflict with each other in problematic ways. URIs with non-empty JSON Pointer fragments are ignored; see ResourceURIs.uris_for() for an explanation.

  • initial_base_uri (Optional[URI]) – A base URI, assumed to be determined in accordance with RFC 3986 §5.1, against which a relative uri parameter should be resolved. If no initial base URI is passed and one is needed, one will be generated using the default_uri_factory parameter.

  • default_uri_factory (Callable[[], URI]) – A callable that produces a unique URI on each invocation so that anonymous resources can be assigned a URI for internal Catalog registration.

  • resolve_references (bool) –

  • kwargs (Any) –

resolve_references()

Resolve references, recursivey walking the document from this node.

The exact behavior of reference resolution is determined by the JSON subclass implementing this interface.

See also references_resolved; implementations should set _references_resolved to True to avoid expensive re-resolution.

If references are not supported, reference resolution trivially succeeds. This is the default behavior.

Return type:

None

property additional_uris: FrozenSet[URI]

URIs other than uri registered with the catalog.

This set is intended to be used for non-JSON Pointer-fragment URIs such as plain name fragments and alternate absolute-URIs under which this resource might be requested, none of which affect the resource’s base URI or are automatically propagated to child resource nodes.

URIs in this set with an empty JSON Pointer fragment are converted to the absolute-URI form, which is semantically equivalent.

If uri (or its empty JSON Pointer fragment equivalent) is in the set assigned to this property, it will be ignored.

To change base_uri and pointer_uri, assign to uri rather thian this attribute.

This set is not guaranteed to be complete, as external code can add resources to catalogs directly.

Setting this attribute will unregister removed URIs and register the added ones. URIs with non-empty JSON Pointer fragments are dropped from this set for reasons described in the documentation for uri-for(). An empty JSON Pointer fragment will be stripped, and the result used (unless it is identical to uri, in which case it wil be ignored(.

property base_uri

The absolute-URI against which relative references are resolved.

property child_resource_nodes: Generator[JSONResource]

All immediate JSONResource descendents.

This ignores intervening non-JSONResource descendants, but does not distinguish between descendents in the same resource or in a distinct embedded resource.

property child_resource_roots: Generator[JSONResource]

Immediate descendents that are roots of embedded resources.

child_resource_nodes with non-roots filtered out.

property children_in_resource: Generator[JSONResource]

Immediate JSONResource descendents in the same resource.

child_resource_nodes, but with roots of distinct embedded resources filtered out, leaving only children within the same resource.

data: None | bool | int | float | str | List[JSON] | Dict[str, JSON]

The instance data.

JSON type

data type

null

None

boolean

bool

number

int | float

string

str

array

list[JSON]

object

dict[str, JSON]

itemclass: Type[JSON]

The JSON class type of child instances.

itemkwargs: Dict[str, Any]

Keyword arguments to the itemclass constructor.

key: str | None

The index of the instance within its parent.

parent: JSON | None

The containing JSON instance.

property parent_in_resource: JSONResource | None

Returns the nearest ancestor resource node in the same resource.

This skips any intervening non-JSONResource ancestor nodes, and returns None if this node is a resource root.

property pointer_uri: URI

The URI of this node using its base URI and a JSON Pointer fragment.

This property is similar to JSON Schema’s “canonical URI”, but is unambiguous and consistent with respect to fragments.

property resource_parent: JSONResource | None

Returns the nearest ancestor that is a JSONResource.

This ancestor may or may not be part of the same resource, see also parent_in_resource

property resource_root: JSONResource

The root this resource, which can differ from document_root.

See also is_resource_root(); if no other ancestor node is indicated as a resource root, this should be equivalent to document_root.

type: str

The JSON type of the instance. One of null, boolean, number, string, array, object.

property uri: URI

The URI identifying the resource in the catalog’s cache.

While pointer_uri gives the location of this node in the JSON structure of the resource, this attribute is intended to be externally-facing when relevant. While the code does not enforce this, callers are recommended to prefer:

If this node is the resource_root, the base URI can be changed by setting this property ao an absolute-URI, or to a URI with a non-JSON Pointer fragment (which will set base_uri to that URI’s base). Setting a non-resource-root URI that disagrees with base_uri is not allowed; see additional_uris for managing alternate URI registration.

See :meth”ResourceURIs.uris_for for an explanation of how JSON Pointer fragment URIs are handled as catalog cache keyes.

Assigning to this URI will unregister the old URI from the catalog and re-register this resource under the new URI, and update base_uri and pointer_uri if appropriate.

class jschon.resource.ResourceURIs(register_uri, property_uri, base_uri, additional_uris)

Data structure for organizing resource document node URIs by use case.

Parameters:
  • register_uri (bool) –

  • property_uri (URI) –

  • base_uri (URI) –

  • additional_uris (Set[URI]) –

__init__(register_uri, property_uri, base_uri, additional_uris)
Parameters:
  • register_uri (bool) –

  • property_uri (URI) –

  • base_uri (URI) –

  • additional_uris (Set[URI]) –

Return type:

None

classmethod pointer_uri_for(node)
classmethod uris_for(node, uri, initial_base_uri, default_uri_factory)

Determine the URIs for various use cases.

Absolute URIs (without a fragment) and URIs with non-JSON Pointer fragments are registered as-is. If a non-JSON Pointer fragment is given for a resource root, the absolute form is assigned to property_uri (and base_uri) while the fragment URI is assigned to additional_uris.

JSON Pointer fragment URIs do not need to be registered with the catalog. However, the empty JSON Pointer is semantically equivalent to not having a fragment, so in that case the absolute portion of that URI is assigned to property_uri and base_uri.

JSON Pointer fragment URIs never appear in additional_uris.

If uri is None and this document node is a resource root, a UUID URN is generated for catalog registration purposes.

Parameters:
  • node – The JSONResource node for which the URIs are being deterimined

  • uri (Optional[URI]) – See pre_recursion_init()

  • initia_base_uri – See pre_recursion_init()

  • default_uri_factory (Callable[[], URI]) – See pre_recursion_init()

  • initial_base_uri (Optional[URI]) –

Return type:

ResourceURIs

additional_uris: Set[URI]

Alternate URIs to register with the catalog.

base_uri: URI

The base URI for the resource.

property_uri: URI

The URI to return from the uri property.

register_uri: bool

Indicates if property_uri should be registered with the catalog.