Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

OntoEnv Python Bindings

Installation

pip install ontoenv

Usage

from ontoenv import OntoEnv
from rdflib import Graph

# Connect creates on first use and graph-free warm-opens on later runs.
env = OntoEnv.connect(".")

# add an ontology from a file path.
# env.add returns the name of the ontology, which is its URI
# e.g. "https://brickschema.org/schema/1.4-rc1/Brick"
brick_name = env.add("../brick/Brick.ttl")
print(f"Added ontology {brick_name}")

# When you add from a URL whose declared ontology name differs (for example a
# versioned IRI served at a versionless URL), ontoenv records that alias. You
# can later refer to the ontology by either the canonical name or the original
# URL when resolving imports or querying.

# get the graph of the ontology we just added
# env.get_graph returns a read-only store-backed rdflib.Graph
brick_graph = env.get_graph(brick_name)
print(f"Brick graph has {len(brick_graph)} triples")

# if you need a mutable in-memory graph, copy it explicitly
mutable_brick_graph = env.copy_graph(brick_name)

# get a read-only view of the full closure of the ontology, including all of its imports
# returns a tuple (ViewGraph, list[str])
brick_closure_graph, _ = env.get_closure(brick_name)
print(f"Brick closure has {len(brick_closure_graph)} triples")

# if you need a mutable materialized closure, copy it explicitly
mutable_brick_closure_graph, _ = env.copy_closure(brick_name)

# you can also add ontologies from a URL
rec_name = env.add("https://w3id.org/rec/rec.ttl")
rec_graph = env.get_graph(rec_name)
print(f"REC graph has {len(rec_graph)} triples")

# you can add an in-memory rdflib.Graph directly
in_memory = Graph()
in_memory.parse(data="""
@prefix owl: <http://www.w3.org/2002/07/owl#> .
<http://example.com/in-memory> a owl:Ontology .
""", format="turtle")
in_memory_name = env.add(in_memory)
print(f"Added in-memory ontology {in_memory_name}")

# if you have an rdflib.Graph with an owl:Ontology declaration,
# you can transitively import its dependencies into the graph
g = Graph()
# this graph just has one triple: the ontology declaration for Brick
g.parse(data="""
@prefix owl: <http://www.w3.org/2002/07/owl#> .
<https://brickschema.org/schema/1.4-rc1/Brick> a owl:Ontology .
""")
# this will load all of the owl:imports of the Brick ontology into 'g'
env.import_dependencies(g)
print(f"Graph with imported dependencies has {len(g)} triples")
env.close()

Using a persistent environment

For persistent use, OntoEnv saves your settings plus a small index of ontology names, imports, aliases, locations, namespaces, and hashes. This lets later connections answer dependency questions without rereading every RDF triple.

Use connect for normal application code:

env = OntoEnv.connect("./ontology-env")
site = env.add("./ontologies/site.ttl")

On the first run, this creates the environment directory, saves its settings, and initializes graph storage. On later runs, the same call loads the saved ontology index. There is no need to check whether the environment exists before connecting.

The context manager is optional. For a long-lived service, connect once during startup and keep the object in application state:

env = OntoEnv.connect("/srv/ontology-env")
application_state.ontoenv = env

# Reuse application_state.ontoenv in request handlers, then close it from the
# web framework's shutdown hook.
application_state.ontoenv.close()

For a short script, with performs the same cleanup automatically:

with OntoEnv.connect("/srv/ontology-env") as env:
    print(env.get_ontology_names())

For a multi-process server, each read-only worker may open its own OntoEnv.connect(path, read_only=True). A persistent environment permits one writer, so do not create an independent writable environment in every worker; route mutations through one writer and serialize them at the application level.

For custom stores, sync="auto" reconnects quickly and reads only graphs the store can identify as changed. If the store cannot identify those graphs, OntoEnv asks for an explicit sync="full" instead of silently scanning everything. This synchronizes direct store changes; it does not check ontology files or URLs. Call env.update() after connecting when source files, remote sources, and their imports should be refreshed.

Most applications never need a different lifecycle method. create is useful for a setup command that must fail if the environment already exists. open is useful when deployment must have prepared the environment in advance and startup must neither create nor synchronize it. adopt explicitly reads every graph in a populated custom store once and records the ontology information OntoEnv needs; it does not fetch network imports. For tests and notebooks that should write no environment files, use OntoEnv(temporary=True).

Refreshing source files and URLs is separate from reconciling a custom graph store. env.update() checks changed local sources and expired remote sources, then follows their imports. env.update(force=True) forces every known source and its dependencies to be reread. To update one ontology and its imports, pass its file or URL directly; its stored graph is replaced automatically:

env.update(source)
env.update(source, force=True)  # reread even when the cached copy looks current

When graphs were changed directly in a custom store, use refresh_from_store() instead. A targeted refresh accepts exact graph IDs. To include the dependency closure currently known to OntoEnv:

report = env.refresh_from_store(graphs=env.list_closure(root))

If the external edit added an entirely new imported graph, use incremental refresh with a store that reports per-graph changes, or request refresh_from_store(full=True).

Namespace prefixes

OntoEnv can extract namespace prefix mappings from ontology source files. Prefixes come from both parser-level declarations (@prefix in Turtle, PREFIX in SPARQL-style syntaxes) and SHACL sh:declare entries.

# Get all namespaces across the entire environment
all_ns = env.get_namespaces()
# {'owl': 'http://www.w3.org/2002/07/owl#', 'brick': 'https://brickschema.org/schema/Brick#', ...}

# Get namespaces for a single ontology
ns = env.get_namespaces("https://brickschema.org/schema/1.4-rc1/Brick")

# Include namespaces from transitive owl:imports
ns_with_imports = env.get_namespaces("https://brickschema.org/schema/1.4-rc1/Brick", include_closure=True)

From the CLI:

ontoenv namespaces                                     # all namespaces
ontoenv namespaces https://example.org/my-ontology     # single ontology
ontoenv namespaces https://example.org/my-ontology --closure   # with imports
ontoenv namespaces --json                              # JSON output

Custom graph store

If you want OntoEnv to write graphs into an existing Python-backed store, pass a graph_store object that implements a small protocol:

class GraphStore:
    # Required
    def add_graph(self, iri: str, graph: Graph, overwrite: bool = False) -> None: ...
    def get_graph(self, iri: str) -> Graph: ...   # used for read-only views (get_*)
    def remove_graph(self, iri: str) -> None: ...
    def graph_ids(self) -> list[str]: ...

    # Optional
    def copy_graph(self, iri: str) -> Graph: ...  # used for mutable copies (copy_*)
                                                  # falls back to get_graph when absent
    def size(self) -> dict[str, int]: ...         # returns {"num_graphs": ..., "num_triples": ...}
    def store_state(self) -> dict[str, str]: ...  # {"id": opaque_id, "revision": opaque_revision}
    def graph_revisions(self) -> dict[str, str]: ... # opaque revision per graph IRI

copy_graph lets stores distinguish between returning a live view (get_graph) and a detached mutable copy (copy_graph). All copy_* methods (copy_graph, copy_closure, copy_union, copy_dataset) dispatch to copy_graph when it is present, and fall back to get_graph otherwise. The get_* methods always use get_graph.

Example:

store = DictGraphStore()
env = OntoEnv(graph_store=store, temporary=True)

For a persistent custom store, use connect:

env = OntoEnv.connect("./environment", graph_store=store)

If the store implements the optional change-reporting methods, OntoEnv can notice external edits and read only the affected graphs. Otherwise, writes through env remain synchronized automatically, while out-of-band edits require sync="full".

Temporary environments save no persistent ontology index. To scan a pre-populated temporary store without the deprecated init_from_store flag:

env = OntoEnv(graph_store=store, temporary=True)
report = env.refresh_from_store(full=True)
print(report.added)

RDFLib store with Rust SPARQL

If you want to use ontoenv as an rdflib store directly, use OntoEnvStore. This gives you normal rdflib.Graph and rdflib.Dataset objects, but executes SPARQL through the Rust backend instead of rdflib's Python query engine.

Use env.get_dataset() to get a read-only rdflib.Dataset view of the env. It uses the zero-copy rdf5d snapshot when a persistent .ontoenv/store.r5tu exists and otherwise falls back to an in-memory view. Use env.copy_dataset() when you need a mutable in-memory dataset.

from rdflib import URIRef
from ontoenv import OntoEnv

env = OntoEnv(path=".demo-env", recreate=True, offline=True, search_directories=["./brick"])
brick_name = env.add("./brick/Brick.ttl")
env.update()
env.flush()

dataset = env.get_dataset()

for row in dataset.query(
    """
    SELECT ?entity ?label
    WHERE {
      GRAPH <https://brickschema.org/schema/1.4/Brick> {
        ?entity <http://www.w3.org/2000/01/rdf-schema#label> ?label .
      }
    }
    LIMIT 5
    """
):
    print(row.entity, row.label)

brick_graph = dataset.graph(URIRef(brick_name))
print(len(brick_graph))
env.close()

Importing ontoenv also registers the rdflib plugin name "ontoenv", so this works too:

from rdflib import Graph
import ontoenv

graph = Graph(store="ontoenv")

See demo_rdflib_store.py for a complete runnable example.

CLI Entrypoint

Installing ontoenv also provides the Rust-backed ontoenv command-line tool:

pip install ontoenv
ontoenv --help

The CLI is identical to the standalone ontoenv-cli binary; see the top-level README for usage.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ontoenv-0.6.0a9.tar.gz (1.3 MB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

ontoenv-0.6.0a9-cp311-abi3-win_amd64.whl (6.5 MB view details)

Uploaded CPython 3.11+Windows x86-64

ontoenv-0.6.0a9-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (66.4 MB view details)

Uploaded CPython 3.11+manylinux: glibc 2.17+ x86-64

ontoenv-0.6.0a9-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (65.4 MB view details)

Uploaded CPython 3.11+manylinux: glibc 2.17+ ARM64

ontoenv-0.6.0a9-cp311-abi3-macosx_11_0_arm64.whl (7.2 MB view details)

Uploaded CPython 3.11+macOS 11.0+ ARM64

ontoenv-0.6.0a9-cp311-abi3-macosx_10_14_x86_64.whl (7.5 MB view details)

Uploaded CPython 3.11+macOS 10.14+ x86-64

ontoenv-0.6.0a9-cp311-abi3-macosx_10_14_x86_64.macosx_11_0_arm64.macosx_10_14_universal2.whl (14.6 MB view details)

Uploaded CPython 3.11+macOS 10.14+ universal2 (ARM64, x86-64)macOS 10.14+ x86-64macOS 11.0+ ARM64

File details

Details for the file ontoenv-0.6.0a9.tar.gz.

File metadata

  • Download URL: ontoenv-0.6.0a9.tar.gz
  • Upload date:
  • Size: 1.3 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for ontoenv-0.6.0a9.tar.gz
Algorithm Hash digest
SHA256 e370aa76ed0d00d4b168855aed9d06a75cc4ae3f859bc892fd5b21ae728f42c1
MD5 8b3ac8c2a3242491a38413c0d1914498
BLAKE2b-256 44c76e6bb97e63da769d9e2de8499efa07b294f716f2c55b639a2d36b7740e71

See more details on using hashes here.

File details

Details for the file ontoenv-0.6.0a9-cp311-abi3-win_amd64.whl.

File metadata

  • Download URL: ontoenv-0.6.0a9-cp311-abi3-win_amd64.whl
  • Upload date:
  • Size: 6.5 MB
  • Tags: CPython 3.11+, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for ontoenv-0.6.0a9-cp311-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 237ba30bfeaee64afbb89018386df90b0f8e256c930ccc9db847c68a56a3220c
MD5 e6fa737c6b597c4de6d257ba94b1c15b
BLAKE2b-256 2b08e7650fca80513e68d05b0e5eace4054199075ad32dc48a9929a6334aa4b1

See more details on using hashes here.

File details

Details for the file ontoenv-0.6.0a9-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for ontoenv-0.6.0a9-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 ffae0541ee2421d433af85e18585b8b8735e6a27112b40525a4f955ddb0b56e3
MD5 5bcd657a77183e38bd6f6c7f4ba41413
BLAKE2b-256 56703f1506c59c0e6977a997eb0409f3bbf2ee03526ce97a2e1a543a057b48f5

See more details on using hashes here.

File details

Details for the file ontoenv-0.6.0a9-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for ontoenv-0.6.0a9-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 40f5db25b27c9b7029d1b76538c1beb6ab0020b3aff96dd10687d8300a7c47ba
MD5 6db517bcdfcee414547daad804d81b92
BLAKE2b-256 cc8b7b30fde407f4192970989af791c6fb6dd3e0b514fd15737ee0591f408a2b

See more details on using hashes here.

File details

Details for the file ontoenv-0.6.0a9-cp311-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for ontoenv-0.6.0a9-cp311-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 072187a0aa16e4753eabe80e5dd2c80f7992adfc386a1c2ee50bdf7c7e849a12
MD5 80d1f4ced934aad02dce2f2ad712b477
BLAKE2b-256 04cb1ba79901b933c221bcb63778e09510895d50ab65c2137162c0e31db0de90

See more details on using hashes here.

File details

Details for the file ontoenv-0.6.0a9-cp311-abi3-macosx_10_14_x86_64.whl.

File metadata

File hashes

Hashes for ontoenv-0.6.0a9-cp311-abi3-macosx_10_14_x86_64.whl
Algorithm Hash digest
SHA256 bf09f781538b167b4679ef9e43ea94283da8633fc6835cb11aef0e77bb660dc8
MD5 e4f12782d6e78c10ea9873844ecb09d0
BLAKE2b-256 d6ee073abb9b4a122ab3cbbb2cae9a048cb10c755f8832d64563e939df96b4be

See more details on using hashes here.

File details

Details for the file ontoenv-0.6.0a9-cp311-abi3-macosx_10_14_x86_64.macosx_11_0_arm64.macosx_10_14_universal2.whl.

File metadata

File hashes

Hashes for ontoenv-0.6.0a9-cp311-abi3-macosx_10_14_x86_64.macosx_11_0_arm64.macosx_10_14_universal2.whl
Algorithm Hash digest
SHA256 ae31958c45e6e7f08c4fe4f8478a8f5cf497a85bc8c7ec79884cd6058f0c52f4
MD5 7040fafaf61c9cae3e89ea62a9da5ac6
BLAKE2b-256 247421d445cae185c760f73274cccd37fbc3cf493f94bbf716779d123f8957d7

See more details on using hashes here.

Release history Release notifications | RSS feed

0.6.2

7 files

0.6.1

7 files

0.6.0

7 files

This release

0.6.0a9 This release

7 files

0.5.5

7 files

0.5.4

7 files

0.5.3

7 files

0.5.2

7 files

0.5.1

7 files

0.5.0

5 files

0.4.0

11 files

0.3.9

2 files

0.3.8

2 files

0.3.7

2 files

0.3.6

2 files

0.3.5

2 files

0.3.4

2 files

0.3.3

2 files

0.3.2

2 files

0.3.1

2 files

0.3.0

2 files

0.2.2

2 files

0.2.0

2 files

0.1.6

2 files

0.1.5

2 files

0.1.4

2 files

0.1.3

2 files

0.1.1

2 files

0.1.0

3 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page