In order to present users for all the correct possibilities in a list of options in a form, the list should not only present all nodes with the type of class expected by the list, but also all nodes with a class type that is a subclass of the originating super class. For this reason, all triples that specify aspects of the class hierarchy of the form schema should be available to the list of options. These triples aren't part of a shacl export of a linkml schema, but they are included in an OWL export. This script allows extracting said triples from an OWL export of a schema and dumps them in a ttl file for use by the shacl-vue app
74 lines
No EOL
2 KiB
Python
74 lines
No EOL
2 KiB
Python
"""
|
|
---------------
|
|
gen_owl_minimal.py
|
|
---------------
|
|
|
|
Generate a serialized graph of triples from a LinkML-turned-OWL schema,
|
|
where the triples only include those with predicate == rdfs:subClassOf
|
|
|
|
"""
|
|
|
|
from argparse import ArgumentParser, RawDescriptionHelpFormatter
|
|
from pathlib import Path
|
|
from rdflib import Graph, term, BNode
|
|
from rdflib.namespace import RDF, RDFS
|
|
import subprocess
|
|
import sys
|
|
|
|
|
|
def get_owl(schema_path):
|
|
""""""
|
|
args = ['gen-owl', str(schema_path)]
|
|
return run_subprocess(args)
|
|
|
|
|
|
def run_subprocess(args):
|
|
return subprocess.run(args, capture_output=True, text=True).stdout
|
|
|
|
|
|
def get_class_hierarchy(schema_path):
|
|
# Generate OWL from the schema
|
|
owl = get_owl(schema_path)
|
|
# Add all triples into the graph
|
|
g = Graph()
|
|
g.parse(data=owl)
|
|
# Add wanted triples to new graph
|
|
new_g = Graph()
|
|
for s, p, o in g.triples((None, RDFS.subClassOf, None)):
|
|
if not isinstance(s, BNode) and not isinstance(o, BNode):
|
|
new_g.add((s, p, o))
|
|
|
|
# serialize
|
|
new_g.serialize(destination=output_path)
|
|
print(f"Graph written to: {str(output_path)}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
parser = ArgumentParser(epilog=__doc__,
|
|
formatter_class=RawDescriptionHelpFormatter)
|
|
parser.add_argument(
|
|
"schema",
|
|
type=str,
|
|
help="Path to the LinkML schema with UI annotations (YAML)",
|
|
)
|
|
parser.add_argument(
|
|
"--output",
|
|
type=str,
|
|
help="""Path to the output 'ttl' file containing all triples.
|
|
If not supplied, the output will be written to 'graph_owl.ttl'
|
|
in the current working directory.""",
|
|
)
|
|
args = parser.parse_args()
|
|
|
|
# 0. Establish some paths
|
|
fp = Path(__file__)
|
|
tools_dir = fp.parent.resolve()
|
|
schema_path = Path(args.schema).resolve()
|
|
curdir = Path.cwd()
|
|
if args.output:
|
|
output_path = Path(args.output).resolve()
|
|
else:
|
|
output_path = curdir / 'graph_owl.ttl'
|
|
|
|
get_class_hierarchy(schema_path=schema_path)
|
|
|