pyrobot is a modern Python ontology toolkit built on py-horned-owl.
It is not a line-for-line port of ROBOT. The design goal is a composable Python API for ontology manipulation, dataframe workflows, and plugin-driven extensions.
From the GitHub repo:
pip install git+https://github.com/cmungall/pyrobot.gitFor local development:
git clone https://github.com/cmungall/pyrobot.git
cd pyrobot
python3 -m venv .venv
. .venv/bin/activate
pip install -e ".[dev]"- ontology loading, creation, cloning, and serialization
- core operations:
merge,extract,filter,convert,annotate,diff,reason,template,query - pandas adapters for components and annotations
- lazy component streams for batch-oriented downstream processing
- entry-point based plugin registry for future operation packs and reasoner backends
- click-based CLI via
pyrobot
The current py-horned-owl and horned-owl ecosystem is strong on parsing, modeling, and serialization. Native reasoning is not exposed as a first-class API in py-horned-owl today, so pyrobot keeps reasoning behind a plugin boundary rather than hard-wiring an incomplete abstraction into the core package.
The built-in reason operation therefore performs structural reasoning over asserted named-class hierarchies and materializes transitive SubClassOf axioms. Full DL reasoners are left as pluggable backends.
from pyrobot import OntologyDocument
from pyrobot.ops import EntityAnnotationChange, ExtractSpec, diff, extract, merge
left = OntologyDocument.from_string(
"""
Prefix(rdfs:=<http://www.w3.org/2000/01/rdf-schema#>)
Prefix(ex:=<http://example.org/>)
Ontology(<http://example.org/left>
Declaration(Class(ex:A))
Declaration(Class(ex:B))
SubClassOf(ex:A ex:B)
)
""",
serialization="ofn",
)
right = merge([left, left.clone()], output_iri="http://example.org/merged")
subset = extract(right, ExtractSpec(seeds={"ex:A"}, max_hops=0))
report = diff(left, subset)
print(report.identical)The package installs a pyrobot console script:
pyrobot --helpConvert an ontology:
pyrobot convert -i edit.owl -o edit.ofn --to ofnExtract a local neighborhood around one or more seed terms:
pyrobot extract -i edit.ofn -o subset.ofn --seed CL:0000540 --seed UBERON:0002107 --max-hops 1Add annotations:
pyrobot annotate \
-i edit.ofn \
-o annotated.ofn \
--entity-annotation 'CL:0000540|rdfs:comment|reviewed by pyrobot' \
--ontology-annotation 'rdfs:comment|release candidate'Run structural reasoning over the asserted hierarchy:
pyrobot reason -i edit.ofn -o reasoned.ofn --backend structuralBuild ontology content from a ROBOT-style template TSV:
ID Label Parent Comment
ID LABEL SC A rdfs:comment
ex:Neuron Neuron ex:Cell created from template
pyrobot template -t terms.tsv -o templated.ofn --ontology-iri http://example.org/templatedRun a SPARQL query:
pyrobot query \
-i templated.ofn \
-q 'PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> SELECT ?s ?o WHERE { ?s rdfs:subClassOf ?o . }'Run a basic graph-pattern query without writing full SPARQL:
pyrobot query \
-i templated.ofn \
--pattern '?child|rdfs:subClassOf|?parent' \
--select ?child \
--select ?parentDiff two ontologies:
pyrobot diff left.ofn right.ofn --json-outputThe current built-in template engine supports a focused subset of ROBOT-style directives:
ID: subject IRI or CURIE for the rowLABEL:rdfs:labelTYPE:class,object property,data property,annotation property, ornamed individualSC: subclass axiomEC: equivalent classes axiomA <property>: literal annotation assertionAI <property>: IRI-valued annotation assertionAL <property>: language-tagged annotation assertion, usingtext@langAT <property> <datatype>: datatype-valued annotation assertion
pytest
pyrobot --help