Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions .github/workflows/artifacts.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
name: Artifacts

on:
push:
branches:
- main
- next
release:
types:
- published
Expand Down
47 changes: 47 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
name: Tests

on:
push:
branches:
- '**' # Triggers on push to all branches
pull_request:
branches:
- '**' # Triggers on pull request to all branches

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
build_and_test:
runs-on: ubuntu-latest
steps:
#- run: cd python && python -m unittest test.py
- uses: actions/checkout@v4
with:
submodules: true
- name: Install uv
uses: astral-sh/setup-uv@v5
with:
enable-cache: true
- name: Set up Python
run: uv python install
- uses: ./.github/actions/setup-rust
with:
target: aarch64-unknown-linux-gnu
version: stable
- run: |
sudo apt-get update && sudo apt-get install -y g++-aarch64-linux-gnu libssl-dev
mkdir .cargo
echo -e "[target.aarch64-unknown-linux-gnu]\nlinker = \"aarch64-linux-gnu-gcc\"" >> .cargo/config.toml
- name: Build rust stuff
run: cargo build --workspace --release
- name: Run rust tests
run: cargo test --workspace --release
- name: Build python package
run: uv run maturin build --release --features abi3
working-directory: ./python
- name: Test python package
run: uv run python -m unittest test.py
working-directory: ./python

14 changes: 10 additions & 4 deletions lib/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,10 @@ use petgraph::graph::{Graph as DiGraph, NodeIndex};
use std::collections::{HashMap, HashSet, VecDeque};
use std::fs;

/// Searches for the .ontoenv directory in the current directory and then recursively up its parent directories.
/// Searches for the .ontoenv directory in the given directory and then recursively up its parent directories.
/// Returns the path to the directory containing the .ontoenv directory if found.
pub fn find_ontoenv_root() -> Option<PathBuf> {
let start_dir = std::env::current_dir().ok()?;
let mut current_dir = Some(start_dir.as_path());
pub fn find_ontoenv_root_from(start_dir: &Path) -> Option<PathBuf> {
let mut current_dir = Some(start_dir);
while let Some(dir) = current_dir {
if dir.join(".ontoenv").is_dir() {
return Some(dir.to_path_buf());
Expand All @@ -36,6 +35,13 @@ pub fn find_ontoenv_root() -> Option<PathBuf> {
None
}

/// Searches for the .ontoenv directory in the current directory and then recursively up its parent directories.
/// Returns the path to the directory containing the .ontoenv directory if found.
pub fn find_ontoenv_root() -> Option<PathBuf> {
let start_dir = std::env::current_dir().ok()?;
find_ontoenv_root_from(&start_dir)
}

/// These are the different ways to refer to an ontology: either
/// by a location (file or URL), or the name of the graph (IRI)
pub enum ResolveTarget {
Expand Down
61 changes: 39 additions & 22 deletions python/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,29 +7,46 @@
## Usage

```python
from ontoenv import Config, OntoEnv
from ontoenv import OntoEnv
from rdflib import Graph

cfg = Config(["../brick"], strict=False, offline=True)

# make environment
env = OntoEnv(cfg)

# creates a new environment in the current directory, or loads
# an existing one. To use a different directory, pass the 'path'
# argument: OntoEnv(path="/path/to/env")
# OntoEnv() will discover ontologies in the current directory and
# its subdirectories
env = OntoEnv()

# 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}")

# get the graph of the ontology we just added
# env.get returns an rdflib.Graph
brick_graph = env.get(brick_name)
print(f"Brick graph has {len(brick_graph)} triples")

# get the full closure of the ontology, including all of its imports
# also returns an rdflib.Graph
brick_closure_graph = env.get_closure(brick_name)
print(f"Brick closure has {len(brick_closure_graph)} triples")

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

# if you have an rdflib.Graph with an owl:Ontology declaration,
# you can transitively import its dependencies into the graph
g = Graph()
# put the transitive owl:imports closure into 'g'
env.get_closure("https://brickschema.org/schema/1.4-rc1/Brick", g)

# or, get the graph directly
g = env.get_closure("https://brickschema.org/schema/1.4-rc1/Brick")

brick = Graph()
brick.parse("Brick.ttl", format="turtle")
# transitively import dependencies into the 'brick' graph, using the owl:imports declarations
env.import_dependencies(brick)

# pull Brick graph out of environment
brick = env.get_graph("https://brickschema.org/schema/1.4-rc1/Brick")

# import graphs by name
env.import_graph(brick, "https://w3id.org/rec")
# 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")
```
46 changes: 46 additions & 0 deletions python/example.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
from ontoenv import Config, OntoEnv, version
from rdflib import Graph
print(version)


cfg = Config(["../brick"], strict=False, offline=False)

print("Make env")
env = OntoEnv(cfg)
print(env)
print("get brick")
g = Graph()
env.get_closure("https://brickschema.org/schema/1.4-rc1/Brick", g)
print(len(g))

print("get brick 2")
brick = Graph()
brick.parse("../brick/Brick.ttl", format="turtle")
env.import_dependencies(brick)
print(len(brick))
brick_name = env.add("https://brickschema.org/schema/1.4/Brick.ttl")
print(f"Added {brick_name}")
del env

print("new env")
env2 = OntoEnv()
print(env2.store_path())

print("get brick again from URL")
brick = env2.get("https://brickschema.org/schema/1.4/Brick")
print(len(brick))
print(brick)
print(type(brick))

print("brick closure", env2.list_closure("https://brickschema.org/schema/1.4/Brick"))

env2.import_graph(brick, "https://w3id.org/rec")
brick.serialize("test.ttl", format="turtle")

print("qudtqk deps", env2.get_dependents('http://qudt.org/2.1/vocab/quantitykind'))

# get an rdflib.Dataset (https://rdflib.readthedocs.io/en/stable/apidocs/rdflib.html#rdflib.Dataset)
ds = env2.to_rdflib_dataset()
for graphname in ds.graphs():
graph = ds.graph(graphname)
print(f"Graph {graphname} has {len(graph)} triples")
5 changes: 5 additions & 0 deletions python/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,10 @@ build-backend = "maturin"

[dependency-groups]
dev = [
"maturin>=1.9.0",
"pytest>=8.3.5",
]

[tool.uv]
# Rebuild package when any rust files change
cache-keys = [{file = "pyproject.toml"}, {file = "Cargo.toml"}, {file = "**/*.rs"}]
Loading
Loading