JSONSchemata 0.0.0.dev62__tar.gz → 0.1.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- jsonschemata-0.1.1/PKG-INFO +8 -0
- {jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/pyproject.toml +5 -5
- jsonschemata-0.1.1/src/JSONSchemata.egg-info/PKG-INFO +8 -0
- jsonschemata-0.1.1/src/JSONSchemata.egg-info/requires.txt +4 -0
- jsonschemata-0.1.1/src/jsonschemata/__init__.py +5 -0
- jsonschemata-0.1.1/src/jsonschemata/edit.py +192 -0
- {jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/registry.py +51 -31
- jsonschemata-0.0.0.dev62/PKG-INFO +0 -8
- jsonschemata-0.0.0.dev62/src/JSONSchemata.egg-info/PKG-INFO +0 -8
- jsonschemata-0.0.0.dev62/src/JSONSchemata.egg-info/requires.txt +0 -4
- jsonschemata-0.0.0.dev62/src/jsonschemata/__init__.py +0 -1
- jsonschemata-0.0.0.dev62/src/jsonschemata/edit.py +0 -80
- {jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/MANIFEST.in +0 -0
- {jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/setup.cfg +0 -0
- {jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/JSONSchemata.egg-info/SOURCES.txt +0 -0
- {jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/JSONSchemata.egg-info/dependency_links.txt +0 -0
- {jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/JSONSchemata.egg-info/not-zip-safe +0 -0
- {jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/JSONSchemata.egg-info/top_level.txt +0 -0
- {jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/array/unique-strings.yaml +0 -0
- {jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/color/css-name.yaml +0 -0
- {jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/color/css.yaml +0 -0
- {jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/color/hex-string.yaml +0 -0
- {jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/color/hsl-array.yaml +0 -0
- {jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/color/hsl-string.yaml +0 -0
- {jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/color/hsla-array.yaml +0 -0
- {jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/color/rgb-array.yaml +0 -0
- {jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/color/rgb-string.yaml +0 -0
- {jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/color/rgba-array.yaml +0 -0
- {jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/config/github/form/body.yaml +0 -0
- {jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/config/github/funding.yaml +0 -0
- {jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/config/github/label/description.yaml +0 -0
- {jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/config/pydata-sphinx-theme.yaml +0 -0
- {jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/config/python/pyproject-entrypoint.yaml +0 -0
- {jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/config/python/pyproject-person.yaml +0 -0
- {jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/config/python/pyproject.yaml +0 -0
- {jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/config/setuptools.yaml +0 -0
- {jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/config/sphinx.yaml +0 -0
- {jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/config/versioningit.yaml +0 -0
- {jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/date/yyyy-mm-dd.yaml +0 -0
- {jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/id/doi.yaml +0 -0
- {jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/id/email.yaml +0 -0
- {jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/id/github/node.yaml +0 -0
- {jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/id/github/rest.yaml +0 -0
- {jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/id/github/user.yaml +0 -0
- {jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/id/linkedin.yaml +0 -0
- {jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/id/orcid.yaml +0 -0
- {jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/id/researchgate.yaml +0 -0
- {jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/id/spdx-license.yaml +0 -0
- {jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/id/twitter.yaml +0 -0
- {jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/integer/non-negative.yaml +0 -0
- {jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/number/non-negative.yaml +0 -0
- {jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/path/dir-name.yaml +0 -0
- {jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/path/posix/absolute-from-cwd.yaml +0 -0
- {jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/string/nonempty.yaml +0 -0
- {jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/string/oneline.yaml +0 -0
- {jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/uri/mailto.yaml +0 -0
- {jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/url/README.md +0 -0
- {jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/url/ftp.yaml +0 -0
- {jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/url/github/user.yaml +0 -0
- {jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/url/http-explicit.yaml +0 -0
- {jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/url/http-ftp-sftp.yaml +0 -0
- {jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/url/http-implicit.yaml +0 -0
- {jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/url/https.yaml +0 -0
- {jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/url/linkedin/company.yaml +0 -0
- {jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/url/linkedin/person.yaml +0 -0
- {jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/url/linkedin/user.yaml +0 -0
- {jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/url/orcid/user.yaml +0 -0
- {jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/url/researchgate/institution.yaml +0 -0
- {jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/url/researchgate/lab.yaml +0 -0
- {jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/url/researchgate/person.yaml +0 -0
- {jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/url/researchgate/user.yaml +0 -0
- {jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/url/sftp.yaml +0 -0
- {jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/url/twitter/user.yaml +0 -0
|
@@ -17,12 +17,12 @@ namespaces = true
|
|
|
17
17
|
# ----------------------------------------- Project Metadata -------------------------------------
|
|
18
18
|
#
|
|
19
19
|
[project]
|
|
20
|
-
version = "0.
|
|
20
|
+
version = "0.1.1"
|
|
21
21
|
name = "JSONSchemata"
|
|
22
22
|
dependencies = [
|
|
23
|
-
"referencing >=
|
|
24
|
-
"PkgData
|
|
25
|
-
"PySerials
|
|
26
|
-
"PyLinks
|
|
23
|
+
"referencing >=0.35,<0.37",
|
|
24
|
+
"PkgData >=0.1,<0.2",
|
|
25
|
+
"PySerials >=0.1,<0.2",
|
|
26
|
+
"PyLinks >=0.1,<0.2",
|
|
27
27
|
]
|
|
28
28
|
requires-python = ">=3.10"
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
"""Utilities for modifying JSON schemas."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations as _annotations
|
|
4
|
+
|
|
5
|
+
from typing import TYPE_CHECKING as _TYPE_CHECKING
|
|
6
|
+
|
|
7
|
+
if _TYPE_CHECKING:
|
|
8
|
+
from collections.abc import Callable
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def required_last(schema: dict) -> dict:
|
|
12
|
+
"""Recursively move ``required`` fields to the end of their schema dict.
|
|
13
|
+
|
|
14
|
+
Some JSON Schema validators (e.g. ``jsonschema`` with a default-filling extension)
|
|
15
|
+
process keywords in the order they appear in the schema dict.
|
|
16
|
+
When ``required`` is encountered *before* ``default`` values have been filled in,
|
|
17
|
+
validation fails even though the missing keys
|
|
18
|
+
would have been supplied by the defaults.
|
|
19
|
+
Moving ``required`` to the end of every schema dict
|
|
20
|
+
ensures that defaults are applied before presence is checked.
|
|
21
|
+
|
|
22
|
+
The function traverses the full schema tree,
|
|
23
|
+
following all standard JSON Schema locations
|
|
24
|
+
that can contain subschemas:
|
|
25
|
+
|
|
26
|
+
* **Single subschemas**: ``if``, ``then``, ``else``, ``not``, ``items``,
|
|
27
|
+
``unevaluatedItems``, ``contains``, ``additionalProperties``,
|
|
28
|
+
``unevaluatedProperties``.
|
|
29
|
+
* **Lists of subschemas**: ``anyOf``, ``allOf``, ``oneOf``, ``prefixItems``.
|
|
30
|
+
* **Dicts of subschemas**: ``properties``, ``patternProperties``,
|
|
31
|
+
``dependentSchemas``.
|
|
32
|
+
|
|
33
|
+
Parameters
|
|
34
|
+
----------
|
|
35
|
+
schema : dict
|
|
36
|
+
The JSON schema to modify. Modified **in-place**.
|
|
37
|
+
|
|
38
|
+
Returns
|
|
39
|
+
-------
|
|
40
|
+
dict
|
|
41
|
+
The same (now modified) schema dict that was passed in.
|
|
42
|
+
"""
|
|
43
|
+
if "required" in schema:
|
|
44
|
+
schema["required"] = schema.pop("required")
|
|
45
|
+
for key in ["anyOf", "allOf", "oneOf", "prefixItems"]:
|
|
46
|
+
if key in schema:
|
|
47
|
+
for subschema in schema[key]:
|
|
48
|
+
required_last(subschema)
|
|
49
|
+
for key in [
|
|
50
|
+
"if",
|
|
51
|
+
"then",
|
|
52
|
+
"else",
|
|
53
|
+
"not",
|
|
54
|
+
"items",
|
|
55
|
+
"unevaluatedItems",
|
|
56
|
+
"contains",
|
|
57
|
+
"additionalProperties",
|
|
58
|
+
"unevaluatedProperties",
|
|
59
|
+
]:
|
|
60
|
+
if key in schema and isinstance(schema[key], dict):
|
|
61
|
+
required_last(schema[key])
|
|
62
|
+
for key in ["properties", "patternProperties", "dependentSchemas"]:
|
|
63
|
+
if key in schema and isinstance(schema[key], dict):
|
|
64
|
+
for subschema in schema[key].values():
|
|
65
|
+
required_last(subschema)
|
|
66
|
+
return schema
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def add_property(
|
|
70
|
+
schema: dict,
|
|
71
|
+
prop: str,
|
|
72
|
+
value: dict,
|
|
73
|
+
conditioner: Callable[[dict, list], bool] | None = None,
|
|
74
|
+
current_path: list[str] | None = None,
|
|
75
|
+
) -> dict:
|
|
76
|
+
"""Inject a property into every ``properties`` block in a JSON schema tree.
|
|
77
|
+
|
|
78
|
+
The function walks the entire schema tree and,
|
|
79
|
+
at each node whose ``properties`` mapping passes the optional ``conditioner``,
|
|
80
|
+
adds ``prop: value`` to that mapping.
|
|
81
|
+
This makes it possible to, for example,
|
|
82
|
+
allow a sentinel key everywhere in a schema
|
|
83
|
+
that would otherwise reject unknown keys
|
|
84
|
+
via ``additionalProperties: false``.
|
|
85
|
+
|
|
86
|
+
Injection rule
|
|
87
|
+
--------------
|
|
88
|
+
``prop`` is added to ``schema["properties"]``
|
|
89
|
+
at a given node when **both** of the following hold:
|
|
90
|
+
|
|
91
|
+
1. The current schema dict contains a ``"properties"`` key.
|
|
92
|
+
2. Either no ``conditioner`` was supplied, or
|
|
93
|
+
``conditioner(schema, current_path)`` returns ``True``.
|
|
94
|
+
|
|
95
|
+
Traversal
|
|
96
|
+
---------
|
|
97
|
+
After the (optional) injection at the current node, the function recurses into every
|
|
98
|
+
standard JSON Schema location that may contain nested subschemas:
|
|
99
|
+
|
|
100
|
+
* **Single subschemas** — ``if``, ``then``, ``else``, ``not``, ``items``,
|
|
101
|
+
``unevaluatedItems``, ``contains``, ``additionalProperties``,
|
|
102
|
+
``unevaluatedProperties``.
|
|
103
|
+
* **Lists of subschemas** — ``anyOf``, ``allOf``, ``oneOf``, ``prefixItems``:
|
|
104
|
+
each element is visited individually.
|
|
105
|
+
* **Dicts of subschemas** — ``properties``, ``patternProperties``,
|
|
106
|
+
``dependentSchemas``: each *value* is visited individually (the values are the
|
|
107
|
+
subschemas; the dict itself is not).
|
|
108
|
+
|
|
109
|
+
Parameters
|
|
110
|
+
----------
|
|
111
|
+
schema : dict
|
|
112
|
+
The root JSON schema to modify. Modified **in-place**.
|
|
113
|
+
prop : str
|
|
114
|
+
Name of the property to inject (e.g. ``"__temp__"``).
|
|
115
|
+
value : dict
|
|
116
|
+
The subschema to assign to the injected property
|
|
117
|
+
(e.g. ``{}`` to accept any value).
|
|
118
|
+
conditioner : Callable[[dict, list[str]], bool] | None, optional
|
|
119
|
+
A callable invoked before each potential injection with two arguments:
|
|
120
|
+
|
|
121
|
+
* ``schema`` — the candidate schema dict at the current traversal node.
|
|
122
|
+
* ``current_path`` — a list of strings tracing the path from the root schema
|
|
123
|
+
to the current node (e.g.
|
|
124
|
+
``["properties[foo]", "anyOf[0]", "patternProperties[^bar_]"]``).
|
|
125
|
+
Useful for context-sensitive decisions such as skipping injection under
|
|
126
|
+
certain branches.
|
|
127
|
+
|
|
128
|
+
Return ``True`` to allow the injection at this node; ``False`` to skip it.
|
|
129
|
+
Recursion into child nodes continues regardless of the return value.
|
|
130
|
+
When ``None``, the property is injected at every node that has
|
|
131
|
+
a ``"properties"`` key.
|
|
132
|
+
current_path : list[str] | None, optional
|
|
133
|
+
Path from the schema root to the current node, used internally during
|
|
134
|
+
recursion and forwarded to ``conditioner``. Callers should leave this as
|
|
135
|
+
``None``; it is initialised to ``[]`` automatically on the first call.
|
|
136
|
+
|
|
137
|
+
Returns
|
|
138
|
+
-------
|
|
139
|
+
dict
|
|
140
|
+
The same (now modified) schema dict that was passed in.
|
|
141
|
+
"""
|
|
142
|
+
if current_path is None:
|
|
143
|
+
current_path = []
|
|
144
|
+
|
|
145
|
+
# Add the property to the current schema
|
|
146
|
+
# if it has a "properties" field and passes the conditioner (if any).
|
|
147
|
+
if "properties" in schema and (
|
|
148
|
+
not conditioner or conditioner(schema, current_path)
|
|
149
|
+
):
|
|
150
|
+
schema["properties"][prop] = value
|
|
151
|
+
|
|
152
|
+
# Recurse into subschemas
|
|
153
|
+
|
|
154
|
+
# Single subschemas
|
|
155
|
+
for key in [
|
|
156
|
+
"if",
|
|
157
|
+
"then",
|
|
158
|
+
"else",
|
|
159
|
+
"not",
|
|
160
|
+
"items",
|
|
161
|
+
"unevaluatedItems",
|
|
162
|
+
"contains",
|
|
163
|
+
"additionalProperties",
|
|
164
|
+
"unevaluatedProperties",
|
|
165
|
+
]:
|
|
166
|
+
if key in schema and isinstance(schema[key], dict):
|
|
167
|
+
add_property(schema[key], prop, value, conditioner, [*current_path, key])
|
|
168
|
+
|
|
169
|
+
# List of subschemas
|
|
170
|
+
for key in ["anyOf", "allOf", "oneOf", "prefixItems"]:
|
|
171
|
+
for idx, subschema in enumerate(schema.get(key, [])):
|
|
172
|
+
add_property(
|
|
173
|
+
subschema,
|
|
174
|
+
prop,
|
|
175
|
+
value,
|
|
176
|
+
conditioner,
|
|
177
|
+
[*current_path, f"{key}[{idx}]"],
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
# Dict of subschemas
|
|
181
|
+
for key in ["properties", "patternProperties", "dependentSchemas"]:
|
|
182
|
+
if key in schema and isinstance(schema[key], dict):
|
|
183
|
+
for property_name, subschema in schema[key].items():
|
|
184
|
+
add_property(
|
|
185
|
+
subschema,
|
|
186
|
+
prop,
|
|
187
|
+
value,
|
|
188
|
+
conditioner,
|
|
189
|
+
[*current_path, f"{key}[{property_name}]"],
|
|
190
|
+
)
|
|
191
|
+
|
|
192
|
+
return schema
|
|
@@ -1,34 +1,41 @@
|
|
|
1
|
+
"""Utilities for creating and managing JSON Schema registries."""
|
|
2
|
+
|
|
1
3
|
from __future__ import annotations as _annotations
|
|
2
4
|
|
|
3
5
|
from typing import TYPE_CHECKING as _TYPE_CHECKING
|
|
4
6
|
|
|
5
|
-
import referencing as _referencing
|
|
6
|
-
from referencing import jsonschema as _ref_jsonschema, retrieval as _ref_retrieval
|
|
7
7
|
import pkgdata as _pkgdata
|
|
8
|
-
import pyserials as _ps
|
|
9
8
|
import pylinks as _pl
|
|
9
|
+
import pyserials as _ps
|
|
10
|
+
import referencing as _referencing
|
|
11
|
+
from referencing import jsonschema as _ref_jsonschema
|
|
12
|
+
from referencing import retrieval as _ref_retrieval
|
|
10
13
|
|
|
11
14
|
from jsonschemata import edit as _edit
|
|
12
15
|
|
|
13
16
|
if _TYPE_CHECKING:
|
|
14
|
-
from
|
|
17
|
+
from collections.abc import Callable, Sequence
|
|
15
18
|
|
|
16
19
|
|
|
17
20
|
def make(
|
|
18
|
-
resources: Sequence[
|
|
21
|
+
resources: Sequence[
|
|
22
|
+
dict | _referencing.Resource | tuple[str, dict | _referencing.Resource]
|
|
23
|
+
]
|
|
24
|
+
| None = None,
|
|
19
25
|
default_specification: _referencing.Specification = _ref_jsonschema.DRAFT202012,
|
|
26
|
+
*,
|
|
20
27
|
crawl: bool = True,
|
|
21
28
|
clean: bool = False,
|
|
22
29
|
dynamic: bool = True,
|
|
23
|
-
retrieval_function: Callable[[str], str | _referencing.Resource] = None,
|
|
30
|
+
retrieval_function: Callable[[str], str | _referencing.Resource] | None = None,
|
|
24
31
|
) -> _referencing.Registry:
|
|
25
32
|
"""Create a JSON Schema registry.
|
|
26
33
|
|
|
27
34
|
Parameters
|
|
28
35
|
----------
|
|
29
36
|
resources
|
|
30
|
-
A list of schema resources to add to the registry. Each resource can be
|
|
31
|
-
a [`referencing.Resource`](https://referencing.readthedocs.io/en/stable/api/#referencing.Resource)
|
|
37
|
+
A list of schema resources to add to the registry. Each resource can be
|
|
38
|
+
a dictionary or a [`referencing.Resource`](https://referencing.readthedocs.io/en/stable/api/#referencing.Resource)
|
|
32
39
|
object. If a schema does not have an "$id",
|
|
33
40
|
the ID must be provided along with the resource as a tuple of (ID, schema).
|
|
34
41
|
default_specification
|
|
@@ -45,8 +52,10 @@ def make(
|
|
|
45
52
|
[Dynamically retrieve](https://referencing.readthedocs.io/en/stable/intro/#dynamically-retrieving-resources)
|
|
46
53
|
and [cache](https://referencing.readthedocs.io/en/stable/intro/#caching)
|
|
47
54
|
references that are not found in the registry.
|
|
48
|
-
If set to True, the default behaviour is as follows
|
|
49
|
-
|
|
55
|
+
If set to True, the default behaviour is as follows
|
|
56
|
+
(see `retrieval_function` for customization):
|
|
57
|
+
If the reference URI starts with "http" or "https",
|
|
58
|
+
the URI is fetched using an HTTP GET request.
|
|
50
59
|
Otherwise, the URI is assumed to be a local filepath,
|
|
51
60
|
which can be either absolute or relative to the current working directory.
|
|
52
61
|
retrieval_function: Callable[[str], str | referencing.Resource], optional
|
|
@@ -55,57 +64,68 @@ def make(
|
|
|
55
64
|
If you want the retrieval function to also cache the retrieved references,
|
|
56
65
|
the function must be decorated with the
|
|
57
66
|
[`@referencing.retrieval.to_cached_resource`](https://referencing.readthedocs.io/en/stable/api/#referencing.retrieval.to_cached_resource)
|
|
58
|
-
decorator, in which case the function must return the reference schema as
|
|
67
|
+
decorator, in which case the function must return the reference schema as
|
|
68
|
+
a JSON string
|
|
59
69
|
(cf. [Referencing Docs](https://referencing.readthedocs.io/en/stable/intro/#caching)).
|
|
60
|
-
If the decorator is not used, the function must return the schema as a
|
|
70
|
+
If the decorator is not used, the function must return the schema as a
|
|
71
|
+
`referencing.Resource` instead.
|
|
72
|
+
|
|
61
73
|
Returns
|
|
62
74
|
-------
|
|
63
75
|
referencing.Registry
|
|
64
76
|
A [`referencing.Registry`](https://referencing.readthedocs.io/en/stable/api/#referencing.Registry)
|
|
65
77
|
object containing all resources.
|
|
66
78
|
"""
|
|
67
|
-
|
|
68
|
-
@_ref_retrieval.to_cached_resource()
|
|
69
|
-
def retrieve_url(uri: str) -> str:
|
|
70
|
-
if uri.startswith(("http://", "https://")):
|
|
71
|
-
return _pl.http.request(url=uri, response_type="str")
|
|
72
|
-
return _ps.write.to_json_string(_ps.read.from_file(path=uri, toml_as_dict=True), sort_keys=False)
|
|
73
|
-
|
|
74
79
|
full_resources = []
|
|
75
80
|
id_resources: list[tuple[str, _referencing.Resource]] = []
|
|
76
81
|
|
|
77
82
|
if not clean:
|
|
78
|
-
|
|
83
|
+
pkg_path = _pkgdata.get_package_path_from_caller(top_level=True)
|
|
84
|
+
schema_dir_path = pkg_path / "_data"
|
|
79
85
|
for schema_filepath in schema_dir_path.glob("**/*.yaml"):
|
|
80
86
|
schema_dict = _ps.read.yaml_from_file(path=schema_filepath)
|
|
81
87
|
_edit.required_last(schema_dict)
|
|
82
88
|
schema = _referencing.Resource.from_contents(
|
|
83
|
-
schema_dict,
|
|
89
|
+
schema_dict,
|
|
90
|
+
default_specification=_ref_jsonschema.DRAFT202012,
|
|
84
91
|
)
|
|
85
92
|
full_resources.append(schema)
|
|
86
93
|
for add_resource in resources or []:
|
|
87
94
|
resource_id = None
|
|
95
|
+
resource = add_resource
|
|
88
96
|
if isinstance(add_resource, dict):
|
|
89
|
-
|
|
90
|
-
add_resource,
|
|
97
|
+
resource = _referencing.Resource.from_contents(
|
|
98
|
+
add_resource,
|
|
99
|
+
default_specification=default_specification,
|
|
91
100
|
)
|
|
92
101
|
elif isinstance(add_resource, (list, tuple)):
|
|
93
102
|
resource_id, resource_dict = add_resource
|
|
94
|
-
|
|
95
|
-
resource_dict,
|
|
103
|
+
resource = _referencing.Resource.from_contents(
|
|
104
|
+
resource_dict,
|
|
105
|
+
default_specification=default_specification,
|
|
96
106
|
)
|
|
97
107
|
if resource_id:
|
|
98
|
-
id_resources.append((resource_id,
|
|
108
|
+
id_resources.append((resource_id, resource))
|
|
99
109
|
else:
|
|
100
|
-
full_resources.append(
|
|
110
|
+
full_resources.append(resource)
|
|
101
111
|
|
|
102
|
-
registry =
|
|
103
|
-
retrieve=retrieval_function or
|
|
104
|
-
|
|
112
|
+
registry = (
|
|
113
|
+
_referencing.Registry(retrieve=retrieval_function or _retrieve_url)
|
|
114
|
+
if dynamic
|
|
115
|
+
else _referencing.Registry()
|
|
116
|
+
)
|
|
105
117
|
if full_resources:
|
|
106
118
|
registry = full_resources @ registry
|
|
107
119
|
if id_resources:
|
|
108
120
|
registry = registry.with_resources(id_resources)
|
|
109
121
|
if crawl:
|
|
110
|
-
registry.crawl()
|
|
122
|
+
registry = registry.crawl()
|
|
111
123
|
return registry
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
@_ref_retrieval.to_cached_resource()
|
|
127
|
+
def _retrieve_url(uri: str) -> str:
|
|
128
|
+
if uri.startswith(("http://", "https://")):
|
|
129
|
+
return _pl.http.request(url=uri, response_type="str")
|
|
130
|
+
file_schema = _ps.read.from_file(path=uri, toml_as_dict=True)
|
|
131
|
+
return _ps.write.to_json_string(file_schema, sort_keys=False)
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
from jsonschemata import edit, registry
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations as _annotations
|
|
2
|
-
|
|
3
|
-
from typing import TYPE_CHECKING as _TYPE_CHECKING
|
|
4
|
-
|
|
5
|
-
if _TYPE_CHECKING:
|
|
6
|
-
from typing import Callable
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
def required_last(schema: dict) -> dict:
|
|
10
|
-
"""Modify JSON schema to recursively put all 'required' fields at the end of the schema.
|
|
11
|
-
|
|
12
|
-
This is done because otherwise the 'required' fields
|
|
13
|
-
are checked by jsonschema before filling the defaults,
|
|
14
|
-
which can cause the validation to fail.
|
|
15
|
-
|
|
16
|
-
Returns
|
|
17
|
-
-------
|
|
18
|
-
dict
|
|
19
|
-
Modified schema.
|
|
20
|
-
Note that the input schema is modified in-place,
|
|
21
|
-
so the return value is a reference to the (now modified) input schema.
|
|
22
|
-
"""
|
|
23
|
-
if "required" in schema:
|
|
24
|
-
schema["required"] = schema.pop("required")
|
|
25
|
-
for key in ["anyOf", "allOf", "oneOf", "prefixItems"]:
|
|
26
|
-
if key in schema:
|
|
27
|
-
for subschema in schema[key]:
|
|
28
|
-
required_last(subschema)
|
|
29
|
-
for key in ["if", "then", "else", "not", "items", "unevaluatedItems", "contains", "additionalProperties", "unevaluatedProperties"]:
|
|
30
|
-
if key in schema and isinstance(schema[key], dict):
|
|
31
|
-
required_last(schema[key])
|
|
32
|
-
for key in ["properties", "patternProperties"]:
|
|
33
|
-
if key in schema and isinstance(schema[key], dict):
|
|
34
|
-
for subschema in schema[key].values():
|
|
35
|
-
required_last(subschema)
|
|
36
|
-
return schema
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
def add_property(
|
|
40
|
-
schema: dict,
|
|
41
|
-
prop: str,
|
|
42
|
-
value: dict,
|
|
43
|
-
conditioner: Callable[[dict, list], bool] | None = None,
|
|
44
|
-
current_path: list[str] | None = None,
|
|
45
|
-
) -> dict:
|
|
46
|
-
"""Recursively add a property to a JSON schema.
|
|
47
|
-
|
|
48
|
-
Parameters
|
|
49
|
-
----------
|
|
50
|
-
schema : dict
|
|
51
|
-
The JSON schema to modify.
|
|
52
|
-
prop : str
|
|
53
|
-
The name of the property to add.
|
|
54
|
-
value : Any
|
|
55
|
-
The value of the property to add.
|
|
56
|
-
conditioner : Callable[[dict, list], bool], optional
|
|
57
|
-
A function that takes a schema and the path to the current schema as arguments
|
|
58
|
-
and returns a boolean indicating whether to add the property to the schema.
|
|
59
|
-
current_path : list[str], optional
|
|
60
|
-
The path to the current schema in the JSON schema hierarchy.
|
|
61
|
-
Returns
|
|
62
|
-
-------
|
|
63
|
-
dict
|
|
64
|
-
The modified schema.
|
|
65
|
-
"""
|
|
66
|
-
if current_path is None:
|
|
67
|
-
current_path = []
|
|
68
|
-
for key in ["anyOf", "allOf", "oneOf", "prefixItems"]:
|
|
69
|
-
if key in schema:
|
|
70
|
-
for idx, subschema in enumerate(schema[key]):
|
|
71
|
-
add_property(subschema, prop, value, conditioner, current_path + [f"{key}[{idx}]"])
|
|
72
|
-
for key in ["if", "then", "else", "not", "items", "unevaluatedItems", "contains", "additionalProperties", "patternProperties", "unevaluatedProperties"]:
|
|
73
|
-
if key in schema and isinstance(schema[key], dict):
|
|
74
|
-
add_property(schema[key], prop, value, conditioner, current_path + [key])
|
|
75
|
-
if "properties" in schema:
|
|
76
|
-
for property_name, subschema in schema["properties"].items():
|
|
77
|
-
add_property(subschema, prop, value, conditioner, current_path + [f"properties[{property_name}]"])
|
|
78
|
-
if not conditioner or conditioner(schema, current_path):
|
|
79
|
-
schema["properties"][prop] = value
|
|
80
|
-
return schema
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/JSONSchemata.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/array/unique-strings.yaml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/color/hex-string.yaml
RENAMED
|
File without changes
|
|
File without changes
|
{jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/color/hsl-string.yaml
RENAMED
|
File without changes
|
{jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/color/hsla-array.yaml
RENAMED
|
File without changes
|
|
File without changes
|
{jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/color/rgb-string.yaml
RENAMED
|
File without changes
|
{jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/color/rgba-array.yaml
RENAMED
|
File without changes
|
{jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/config/github/form/body.yaml
RENAMED
|
File without changes
|
{jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/config/github/funding.yaml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/config/python/pyproject.yaml
RENAMED
|
File without changes
|
{jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/config/setuptools.yaml
RENAMED
|
File without changes
|
|
File without changes
|
{jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/config/versioningit.yaml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/integer/non-negative.yaml
RENAMED
|
File without changes
|
{jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/number/non-negative.yaml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/url/http-explicit.yaml
RENAMED
|
File without changes
|
{jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/url/http-ftp-sftp.yaml
RENAMED
|
File without changes
|
{jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/url/http-implicit.yaml
RENAMED
|
File without changes
|
|
File without changes
|
{jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/url/linkedin/company.yaml
RENAMED
|
File without changes
|
{jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/url/linkedin/person.yaml
RENAMED
|
File without changes
|
{jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/url/linkedin/user.yaml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/url/researchgate/lab.yaml
RENAMED
|
File without changes
|
{jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/url/researchgate/person.yaml
RENAMED
|
File without changes
|
{jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/url/researchgate/user.yaml
RENAMED
|
File without changes
|
|
File without changes
|
{jsonschemata-0.0.0.dev62 → jsonschemata-0.1.1}/src/jsonschemata/_data/url/twitter/user.yaml
RENAMED
|
File without changes
|