Validate against an OO-LD schema

an oo-ld quantityvalue schema on the left and a valid measurement instance on the right

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.

See also