| """JCAT ontology engine β Hugging Face Space. |
| |
| A Gradio front-end over the open `jcat` engine. Paste terms, pick taxonomy or ontology, |
| choose the layer depth, and get standards-compliant SKOS/OWL Turtle plus a readable tree. |
| When the optional engine (open-ontologies-lite / Oxigraph) is installed, the Space also |
| validates the graph for real and runs live SPARQL over it. Mirrors the demo at |
| https://jcatlabs.com/#demo. |
| """ |
| import json |
|
|
| import gradio as gr |
|
|
| import jcat |
| from jcat import Graph |
| from jcat.core import build_tree, parse_terms |
|
|
| EXAMPLE = """credit risk |
| market risk |
| operational risk |
| liquidity risk |
| savings account |
| current account |
| business account |
| fixed deposit |
| retail customer |
| corporate customer |
| private customer |
| mortgage loan |
| personal loan |
| business loan""" |
|
|
| DEFAULT_SPARQL = "SELECT ?s ?p ?o WHERE { ?s ?p ?o } LIMIT 15" |
|
|
|
|
| def _tree_text(node, prefix=""): |
| lines = [] |
| n = len(node.children) |
| for i, c in enumerate(node.children): |
| last = i == n - 1 |
| lines.append(prefix + ("ββ " if last else "ββ ") + c.label) |
| lines.append(_tree_text(c, prefix + (" " if last else "β "))) |
| return "\n".join(l for l in lines if l) |
|
|
|
|
| def _is_owl(mode): |
| return mode.startswith("Ont") |
|
|
|
|
| def run(text, mode, depth): |
| terms = parse_terms(text) |
| if not terms: |
| return "Add a few terms first.", "", "β" |
| g = Graph(terms) |
| owl = _is_owl(mode) |
| ttl = g.ontology(int(depth)) if owl else g.taxonomy(int(depth)) |
| root = build_tree(terms, "ontology" if owl else "taxonomy", int(depth)) |
| if jcat.has_engine(): |
| rep = g.validate(mode="ontology" if owl else "taxonomy", depth=int(depth)) |
| ok = "valid" if rep.get("valid") else "INVALID" |
| status = f"β {ok} Β· {rep.get('triples')} triples Β· validated by open-ontologies-lite (Oxigraph)" |
| else: |
| status = "light mode β engine not installed (synthesis only)" |
| return ttl, (root.label + "\n" + _tree_text(root)), status |
|
|
|
|
| def run_sparql(text, mode, depth, sparql): |
| if not jcat.has_engine(): |
| return "Engine not available in this Space." |
| terms = parse_terms(text) |
| if not terms: |
| return "Add terms first." |
| try: |
| res = Graph(terms).query( |
| sparql, mode="ontology" if _is_owl(mode) else "taxonomy", depth=int(depth) |
| ) |
| rows = res.get("rows", res) |
| return json.dumps(rows, indent=2) |
| except Exception as e: |
| return f"Error: {e}" |
|
|
|
|
| with gr.Blocks(title="JCAT ontology engine", theme=gr.themes.Soft(primary_hue="green")) as demo: |
| gr.Markdown( |
| "# π± JCAT ontology engine\n" |
| "Paste a flat list of terms. Get a standards-compliant **SKOS taxonomy** or " |
| "**OWL ontology**, validated for real and queryable with SPARQL. This is the open " |
| "[`jcat`](https://github.com/fabio-rovai/jcat) engine running on " |
| "[open-ontologies-lite](https://pypi.org/project/open-ontologies-lite/) " |
| "(Oxigraph), the same stack behind [jcatlabs.com](https://jcatlabs.com). Free forever." |
| ) |
| with gr.Row(): |
| with gr.Column(): |
| inp = gr.Textbox(EXAMPLE, lines=14, label="Your terms") |
| mode = gr.Radio( |
| ["Taxonomy (SKOS)", "Ontology (OWL)"], |
| value="Taxonomy (SKOS)", label="Output", |
| ) |
| depth = gr.Slider(1, 3, value=2, step=1, label="Layer depth") |
| btn = gr.Button("Give it a try", variant="primary") |
| with gr.Column(): |
| status = gr.Markdown("β") |
| tree = gr.Textbox(label="Structure", lines=8) |
| ttl = gr.Code(label="Turtle") |
| with gr.Accordion("Run SPARQL over the graph (powered by open-ontologies-lite)", open=False): |
| sparql = gr.Textbox(DEFAULT_SPARQL, lines=3, label="SPARQL") |
| sbtn = gr.Button("Run query") |
| sout = gr.Code(label="Results") |
| sbtn.click(run_sparql, [inp, mode, depth, sparql], sout) |
|
|
| btn.click(run, [inp, mode, depth], [ttl, tree, status]) |
| demo.load(run, [inp, mode, depth], [ttl, tree, status]) |
|
|
| if __name__ == "__main__": |
| demo.launch() |
|
|