Skip to content

Latest commit

 

History

History
91 lines (69 loc) · 3.45 KB

File metadata and controls

91 lines (69 loc) · 3.45 KB

Forking this into your product

There's no domain code to strip — you supply your core namespace and your spec table. Wiring it into your stack is three steps.

1. Point the namespace at your core ontology

The generator resolves each spec's bound class local-name against a namespace IRI. Default is the neutral http://example.org/ontology/core/; pass your own:

from ontology_config_generator import generate_configs

NS = "https://ontology.acme.example/core/"   # YOUR core ontology IRI
generate_configs(spec_table, "extension.ttl", "out/", namespace=NS)

A class local-name "Region" in a spec then binds to <NS>Region in the graph.

2. Declare your spec table

Each row says: which file, which JSON key holds the extracted list, and which class(es) feed it. Keep it in one place — it is the auditable map from ontology concepts to config files.

from ontology_config_generator import ConfigSpec

SPEC_TABLE = [
    ConfigSpec(filename="regions.json",  extract={"regions": "Region"}),
    ConfigSpec(filename="roles.json",    extract={"roles": "Role"}),
    # one key can pull from SEVERAL classes (extractions are concatenated):
    ConfigSpec(filename="parties.json",  extract={"parties": ["Person", "Organization"]}),
    # a config the TTL has nothing to extract for keeps a fixed shape:
    ConfigSpec(filename="glossary.json", static={"terms": [], "synonyms": []}),
]

Or keep it as JSON and load it (handy for non-engineer review / version control):

// specs.json
{ "specs": [
    { "filename": "regions.json", "extract": { "regions": "Region" } },
    { "filename": "glossary.json", "extract": {}, "static": { "terms": [] } }
]}
python -m ontology_config_generator \
  --extension extension.ttl --spec-table specs.json \
  --output-dir out/ --namespace https://ontology.acme.example/core/

3. (Optional) supply a starter-shape directory

If your runtime expects a fixed JSON shape even when the ontology has nothing to contribute yet, keep read-only starter templates and pass starter_dir=. The starter is the base; a non-empty extraction overrides its list, an empty one leaves it intact:

generate_configs(spec_table, "extension.ttl", "out/",
                 namespace=NS, starter_dir="config_templates/")

What the extractor gives you

For each bound class, extract_named returns every named subclass and named individual as {"id", "label", "description"}:

  • id — the IRI's last path/fragment segment (the local name);
  • labelrdfs:label if present, else id;
  • descriptionrdfs:comment if present, else "".

Blank nodes are skipped and each subject appears once. If you need richer fields (extra data properties, etc.), wrap or replace extract_named and keep the generate_configs flow — the merge + provenance stamping is independent of the row shape.

What NOT to change

  • Determinism — don't introduce an LLM or randomness into the compile; the whole point is that configs are a reproducible function of the graph.
  • Degrade-open — keep the missing/unparseable-extension path yielding valid starter-shaped configs, so the step is safe to run unconditionally in a pipeline.
  • The lazy rdflib import — keep heavy imports inside the functions that parse a graph so import ontology_config_generator works without rdflib.
  • The _generated provenance block — it's what makes a generated config traceable back to its source graph.