Skip to content

About

Schema and Generator that generates graviola specific JSON Schema and side UI Schemas from LinkML

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

graviola-linkml

Generate Graviola-ready artifacts from LinkML schemas.

Compared to stock LinkML JSON Schema output, the generator:

  • emits @id only when the class has a LinkML identifier slot; always emits @type with the class IRI
  • keeps LinkML identifier slots (e.g. id with identifier: true) as ordinary properties when declared on the class
  • multivalued inlined class refs are arrays of $ref, not ID-keyed dicts (no __identifier_optional defs)
  • lists a property under required only when that slot has required: true in LinkML

The CLI creates:

  • <schema-stem>.schema.json (Graviola JSON Schema)
  • <schema-stem>.gra.side-schema.json (UI / app side-schema: labels, primary fields, form/detail/table overrides, menu, metadata)
  • <schema-stem>.calc-profile.json (calculated-fields sidecar; via calc-profile or bundle)
  • <schema-stem>.search-facet.json (fulltext + facets; via search-facet or bundle)

Worked Example (contract style)

The example contract is committed in examples/collective-mind-schema.yml. It includes:

  • relations with inverse declarations (memberOf <-> members, hostBody <-> hostedMinds)
  • gra: namespace annotations (gra:label, property-level gra:primaryLabel)

Generate the outputs exactly as documented:

nix run .#generate -- ./examples/collective-mind-schema.yml -o ./examples/collective-mind.schema.json
nix run .#side-schema -- ./examples/collective-mind-schema.yml -o ./examples/collective-mind.gra.side-schema.json
# or all artifacts:
nix run .#bundle -- ./examples/collective-mind-schema.yml -d ./examples

Source excerpt (examples/collective-mind-schema.yml):

classes:
  Individual:
    annotations:
      gra:label: "Individual Being"
    slots: [name, embodiedMind, memberOf]
  Collective:
    annotations:
      gra:label: "Collective"
    slots: [title, members]
slots:
  name:
    annotations:
      gra:primaryLabel: true
  title:
    annotations:
      gra:primaryLabel: true
  memberOf:
    range: Collective
    inlined: true
    inverse: members
  members:
    range: Individual
    multivalued: true
    inlined: true

Generated excerpt (examples/collective-mind.schema.json):

{
  "definitions": {
    "Collective": {
      "properties": {
        "@id": { "type": "string" },
        "@type": { "type": "string", "const": "https://example.org/collective-mind/Collective" },
        "members": {
          "items": { "$ref": "#/definitions/Individual" },
          "type": "array"
        },
        "title": { "type": "string" }
      }
    },
    "Individual": {
      "properties": {
        "@id": { "type": "string" },
        "@type": { "type": "string", "const": "https://example.org/collective-mind/Individual" },
        "id": { "type": "string" },
        "memberOf": { "$ref": "#/definitions/Collective" },
        "name": { "type": "string" }
      }
    }
  }
}

Generated excerpt (examples/collective-mind.gra.side-schema.json):

{
  "primaryFields": {
    "Individual": { "label": "name" },
    "Collective": { "label": "title" }
  },
  "typeNameLabelMap": {
    "Individual": "Individual Being",
    "Collective": "Collective"
  }
}

Run

Nix (no install)

From this repo:

nix run .#generate -- ./examples/collective-mind-schema.yml
nix run .#side-schema -- ./examples/collective-mind-schema.yml
nix run .#calc-profile -- ./tests/fixtures/garden_fee.yaml
nix run .#bundle -- ./tests/fixtures/item_schema_annotated.yaml

From GitHub:

nix run github:graviola-la/graviola-linkml#generate -- ./model.yaml -o ./model.schema.json
nix run github:graviola-la/graviola-linkml#side-schema -- ./model.yaml -o ./model.gra.side-schema.json
nix run github:graviola-la/graviola-linkml#bundle -- ./model.yaml -d ./out

Full CLI help:

nix run . -- --help

Python / uv

uv sync
uv run graviola-linkml --help
uv run graviola-linkml generate ./examples/collective-mind-schema.yml
uv run graviola-linkml side-schema ./examples/collective-mind-schema.yml

CLI

  • generate <schema.yaml>
    • -o, --output <path> (default: <schema-stem>.schema.json)
    • --indent <n> (default: 2)
  • side-schema <schema.yaml>
    • -o, --output <path> (default: <schema-stem>.gra.side-schema.json)
  • calc-profile <schema.yaml>
    • --schema-output <path> / --sidecar-output <path>
    • --indent <n>
  • search-facet <schema.yaml>
    • -o, --output <path> (default: <schema-stem>.search-facet.json)
  • bundle <schema.yaml>
    • -d, --output-dir <path> — writes .schema.json, .gra.side-schema.json, .calc-profile.json, .search-facet.json

Nix Dev Shell

nix develop

Inside the shell, graviola-linkml, uv, and ruff are available.

Local Development

uv sync --extra dev
uv run pytest -v
uv run ruff check .
uv run mypy src

Annotation Vocabulary Publishing

.github/workflows/publish-schema.yml builds and deploys artifacts from annotation-vocab/graviola-annotations.yaml:

  • Turtle (.ttl)
  • JSON-LD (.jsonld)
  • HTML docs (MkDocs)
  • source YAML + .htaccess

About

Schema and Generator that generates graviola specific JSON Schema and side UI Schemas from LinkML

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages