Validate against an OO-LD schema¶
Source: examples/panels/monacoeditor/monacoeditor_oold_min.py
Test: tests/panels/monacoeditor/examples/test_monacoeditor_oold_min.py
The same side-by-side layout as the minimal example, but the schema is a real OO-LD document pulled from a public registry: the QuantityValue schema for physical measurements.
The code¶
The QuantityValue schema is fetched once with urllib.request.urlopen at module import, and the example instance it ships becomes the starting data document:
from urllib.request import urlopen
import panel as pn
from panelini.panels.monacoeditor import MonacoEditor
# Resolves via w3id.org to schemas.oo-ld.org.
SCHEMA_URL = "https://w3id.org/oo-ld/schemas/quantities/dev/QuantityValue.schema.json"
with urlopen(SCHEMA_URL) as response: # noqa: S310
SCHEMA = json.load(response)
# The schema ships its own example instance; use it as the starting document.
DATA = SCHEMA["examples"][0]
The app itself is one Viewer that wires that schema and data into two editors:
class App(pn.viewable.Viewer):
def __init__(self, **params):
super().__init__(**params)
# The schema is shown exactly as the registry serves it, `$schema` included: that
# line is what marks it as OO-LD. Monaco resolves nothing over the network, so it
# would otherwise flag that pointer as unresolvable. The left editor is a viewer,
# not a validated document, so silence the complaint rather than edit the schema.
self.schema_editor = MonacoEditor(
value=json.dumps(SCHEMA, indent=2), schema_request="ignore", sizing_mode="stretch_both"
)
self.data_editor = MonacoEditor(
value=json.dumps(DATA, indent=2), json_schema=SCHEMA, sizing_mode="stretch_both"
)
self.schema_editor.param.watch(self.on_schema_change, "value")
self.status = pn.pane.Markdown(f"Schema fetched from `{SCHEMA_URL}`")
# stretch_both only reaches the editors if every container above them stretches
# too, so the whole chain says so. The status line keeps its natural height and
# the row takes the rest.
self._view = pn.Column(
pn.Row(
pn.Column(f"### OO-LD Schema: {SCHEMA['title']}", self.schema_editor, sizing_mode="stretch_both"),
pn.Column("### QuantityValue instance", self.data_editor, sizing_mode="stretch_both"),
sizing_mode="stretch_both",
),
self.status,
sizing_mode="stretch_both",
)
def on_schema_change(self, event):
try:
self.data_editor.json_schema = json.loads(event.new)
except json.JSONDecodeError as exc:
self.status.object = f"Schema is not valid JSON: {exc}"
else:
self.status.object = "Schema applied."
def __panel__(self):
return self._view
The fetch runs in Python at import time, so the browser makes no cross-origin request and nothing depends on oo-ld.org being reachable once the app is up. The trade-off: Monaco cannot follow the schema’s own $schema pointer either, so the left editor uses schema_request="ignore" to show the document exactly as authored instead of flagging that pointer as unresolvable.
OO-LD schemas are ordinary JSON Schema plus a JSON-LD @context and x-oold-* annotations. Monaco ignores those extra keywords when validating, so value, unit and standard_uncertainty behave as plain JSON Schema properties.
What you’ll see¶
graph LR
registry(["OO-LD registry<br/>schemas.oo-ld.org"])
schema(["Schema editor<br/>left"])
data(["QuantityValue instance<br/>right, validated"])
registry -- "urlopen at import" --> schema
schema -- "json_schema" --> data
classDef ed fill:#0d7377,stroke:#095c5f,color:#ffffff
classDef ext fill:#6366f1,stroke:#4f46e5,color:#ffffff
class schema,data ed
class registry ext
The left editor shows the fetched schema and the right validates the bundled measurement instance against it; a “Schema fetched from …” status line runs along the bottom, under both editors.