Quickstart: validate data

Go from zero to a passing (and failing) validation in a few minutes. You’ll play both sides: publish a tiny ontology with a SHACL shape from a GitHub repo, then use the client to validate data against it.

Already published an ontology, or just want to share one without SHACL shapes or a client install? Quickstart: publish & discover is the shorter path — this page adds shapes and validation on top of it.

How Ontoshire works#

  • Your ontology and shapes live in your GitHub repo. Ontoshire doesn’t host your source — it reads it from there.
  • You register the repo once. That links it and installs a webhook. Registering doesn’t publish anything by itself.
  • A git tag is a version. Ontoshire only ever ingests tags — never branch pushes, never HEAD. The tag name becomes the version in owner/repo@version.
  • Consumers pull that pinned coordinate, and the client validates their data against it locally — the data itself never leaves their environment.
What you need: a Ontoshire account (sign in with GitHub), Python 3.10+, and a GitHub repo you can push a tag to — that repo is where your ontology and shapes will live, and where Ontoshire reads them from.
Testing a local / self-hosted instance? Point the client at your backend and install from source:
export ONTOGATE_API_URL=http://localhost:3001/api/v1
pip install -e ./ontogate-client
With that set, ontogate login opens your local http://localhost:3000/activate page. Everything below works the same otherwise.

1. Install the client#

shell
pip install ontogate          # CLI + Python SDK — installs the `ontogate` command

Check it’s on your PATH:

shell
$ ontoshire --version
ontoshire 0.1.0

2. Publish your ontology#

Create a repo with two files, one defining a class and one SHACL shape constraining it. A minimal pair:

person.ttl
@prefix owl:  <http://www.w3.org/2002/07/owl#> .
@prefix ex:   <http://example.org/people#> .

<http://example.org/people> a owl:Ontology .
ex:Person a owl:Class .
shapes.ttl
@prefix sh:   <http://www.w3.org/ns/shacl#> .
@prefix ex:   <http://example.org/people#> .
@prefix xsd:  <http://www.w3.org/2001/XMLSchema#> .

ex:PersonShape a sh:NodeShape ;
    sh:targetClass ex:Person ;
    sh:property [
        sh:path ex:email ;
        sh:minCount 1 ;
        sh:nodeKind sh:IRI ;
        sh:message "A Person must have at least one email."
    ] .
  1. Commit both files to a GitHub repo.
  2. Tag and push — the tag name is what the version will be called:
    shell
    git tag v1.0.0
    git push origin v1.0.0
  3. In Ontoshire, go to My Repositories → + Register repo and pick the repo. This links it and installs a webhook — it doesn’t publish anything yet.
  4. The Publish a version dialog opens right after registering: pick the v1.0.0 tag, choose Public or Private (Private needs Pro), and watch live progress (fetching → validating → writing → indexing) until it’s live. It reopens any time from My Repositories → Publish version.

You now have a pinned schema at your-org/people@v1.0.0 (substitute your own owner/repo below). Push a later tag and it publishes automatically — each repo has an auto-publish switch, on by default. See Publishing for the full mechanics, including multi-file ontologies and the shapes conventions.

3. Get a token#

That’s the publisher side done — the rest of this guide is the consumer side. Every schema pull needs a read-only token. For local development, the easiest path is the device login — it opens a browser, you approve, and the token is written to ~/.ontogate/credentials:

ontogate login
$ ontogate login
To authorize this device, visit:

    https://ontoshire.com/activate

and enter the code:

    BCDF-GH23

Waiting for approval…
✓ Logged in. Token stored in ~/.ontogate/credentials.

Prefer to manage it yourself? Create one under Settings → API Tokens and export it as ONTOGATE_API_TOKEN. Either way, see the token guide for the details.

4. Validate conforming data#

Save a dataset that satisfies the shape:

good.ttl
@prefix ex: <http://example.org/people#> .

ex:alice a ex:Person ;
    ex:email <mailto:alice@example.org> .
shell
$ ontogate validate --schema your-org/people@v1.0.0 --data good.ttl
your-org/people@v1.0.0  [self-contained, inference=none]  ✓ conforms
$ echo $?
0

Exit code 0 means it conforms. Wire that into CI and a bad dataset fails the build.

5. Break it and read the report#

Now a dataset that violates the shape (no email):

bad.ttl
@prefix ex: <http://example.org/people#> .

ex:bob a ex:Person .
shell
$ ontogate validate --schema your-org/people@v1.0.0 --data bad.ttl
your-org/people@v1.0.0  [self-contained, inference=none]  ✗ 1 result(s)
  [Violation] http://example.org/people#bob · http://example.org/people#email (MinCountConstraintComponent)
      A Person must have at least one email.
$ echo $?
1

Exit code 1 is a clean non-conforming verdict. For machine-readable output, add --format json:

--format json
{
  "conforms": false,
  "schema": "your-org/people@v1.0.0",
  "mode": "self-contained",
  "contextDepth": null,
  "inference": "none",
  "results": [
    {
      "focusNode": "http://example.org/people#bob",
      "resultPath": "http://example.org/people#email",
      "sourceConstraintComponent": "MinCountConstraintComponent",
      "severity": "Violation",
      "message": "A Person must have at least one email.",
      "value": null
    }
  ]
}

6. Optional: validate against a live store#

If your data references nodes that already live in a target triple store, point the client at it and only your payload’s own violations are reported:

shell
ontogate validate --schema your-org/people@v1.0.0 --data good.ttl \
  --target-endpoint http://localhost:7200/repositories/prod \
  --context-depth 1

See the client reference for contextual mode, endpoint auth, inference, and every flag.

If something goes wrong#

  • Exit code 2 is an operational error, not a validation failure. The message on stderr says which: no token, schema not found, or an unreachable endpoint.
  • “No API token” — run ontogate login or set ONTOGATE_API_TOKEN.
  • “not found, or your token can’t access it” — check the owner/repo@version spelling and that the version is published. Private schemas are visible only to their owner.

Full exit-code and troubleshooting reference lives in the client reference.