Python bindings for Reasonable, a reasonably fast OWL 2 RL reasoner
Project description
reasonable (Python bindings)
Python bindings for Reasonable — a reasonably fast OWL 2 RL reasoner implemented in Rust. This package exposes a small, typed API over rdflib terms to run materialization on RDF graphs or files.
Quick Usage
Load from files (Turtle/N3) and materialize inferred triples:
import reasonable
r = reasonable.PyReasoner()
r.load_file("../example_models/ontologies/Brick.n3")
r.load_file("../example_models/small1.n3")
out = r.reason() # list[tuple[rdflib.term.Node, Node, Node]]
print(len(out))
Reason directly over an rdflib Graph:
import rdflib
import reasonable
from rdflib.term import URIRef
g = rdflib.Graph()
g.add((URIRef("urn:s"), URIRef("urn:p"), URIRef("urn:o")))
r = reasonable.PyReasoner()
r.from_graph(g)
triples = r.reason()
# Optionally collect into a new Graph
g_out = rdflib.Graph()
for s, p, o in triples:
g_out.add((s, p, o))
print(len(g_out))
Incremental Reasoning with Retraction
Use update_graph() to replace the reasoner's base triples when your graph changes. The reasoner automatically computes a diff and selects incremental materialization (additions only) or full re-materialization (if removals detected):
import rdflib
import reasonable
from rdflib import URIRef, RDF
ontology = rdflib.Graph()
ontology.parse("my_ontology.ttl")
data = rdflib.Graph()
data.add((URIRef("urn:sensor1"), RDF.type, URIRef("urn:TemperatureSensor")))
r = reasonable.PyReasoner()
r.from_graph(ontology + data)
triples = r.reason() # full materialization
# Later, data changes...
data.remove((URIRef("urn:sensor1"), RDF.type, URIRef("urn:TemperatureSensor")))
data.add((URIRef("urn:sensor2"), RDF.type, URIRef("urn:HumiditySensor")))
r.update_graph(ontology + data) # replaces base, auto-detects diff
triples = r.reason() # full re-mat (removals detected)
Install
- Runtime dependency:
rdflib - If you have a prebuilt wheel:
pip install dist/reasonable-*.whl - Build from source (see below) if no wheel is available for your platform.
Developer Install (from source)
Using uv (recommended for local dev):
cd python
# Install project dependencies (including dev tools) into a managed venv
uv sync --group dev
# Build and develop-install the extension module
uv run maturin develop -b pyo3 --release
# Sanity check
uv run python -c "import reasonable; print(reasonable.__version__)"
Without uv (system/venv):
cd python
python -m venv .venv && . .venv/bin/activate # or use your env
pip install -U maturin
maturin develop -b pyo3 --release
python -c "import reasonable; print(reasonable.__version__)"
API Reference
reasonable.PyReasoner()load_file(path: str) -> None- Load triples from a Turtle or N3 file. Appends to existing base triples. Raises
OSErroron missing/invalid paths.
- Load triples from a Turtle or N3 file. Appends to existing base triples. Raises
from_graph(graph_or_iterable) -> None- Appends triples from an rdflib
Graph(or any iterable of 3-tuples) to the base. Useupdate_graph()instead if you need retraction support.
- Appends triples from an rdflib
update_graph(graph_or_iterable) -> bool- Replaces the base triples with the contents of the given graph. Computes a diff against the current base: if only additions are found, the next
reason()uses incremental materialization; if any removals are detected, it triggers a full re-materialization. ReturnsTrueif removals were detected,Falseotherwise.
- Replaces the base triples with the contents of the given graph. Computes a diff against the current base: if only additions are found, the next
reason() -> list[tuple[Node, Node, Node]]- Runs OWL 2 RL materialization and returns all known triples (base + inferred) as rdflib nodes. After the first call, subsequent calls are incremental (only processing newly added triples) unless removals were detected via
update_graph().
- Runs OWL 2 RL materialization and returns all known triples (base + inferred) as rdflib nodes. After the first call, subsequent calls are incremental (only processing newly added triples) unless removals were detected via
reason_full() -> list[tuple[Node, Node, Node]]- Forces a full re-materialization from base triples, ignoring any incremental state. Equivalent to
clear()followed byreason().
- Forces a full re-materialization from base triples, ignoring any incremental state. Equivalent to
clear() -> None- Resets all inferred state while keeping base triples. The next
reason()call will perform a full re-materialization.
- Resets all inferred state while keeping base triples. The next
get_base_triples() -> list[tuple[Node, Node, Node]]- Returns the current base (non-inferred) triples as rdflib nodes. Useful for debugging.
Building Wheels
Build release wheels into dist/:
cd python
uv run maturin build --release --out dist
Install the built wheel:
pip install dist/reasonable-*.whl
Requirements
- Python 3.9+ (ABI3, built with
pyo3/abi3-py39) - Rust toolchain (
rustup,cargo) for local builds maturinfor building wheelsrdflib(runtime dependency)
Testing
Run the Python test suite (uses pytest and rdflib):
cd python
uv run pytest -q
Alternatively, with a local venv:
cd python
pip install -U maturin pytest rdflib
maturin develop -b pyo3 --release
pytest -q
Compatibility Notes
- Python: 3.9+ is required due to the ABI3 setting in the Rust crate (
abi3-py39). - Platforms: macOS, Linux, and Windows are supported by PyO3/maturin; building from source requires a Rust toolchain.
Troubleshooting
ModuleNotFoundError: No module named 'reasonable':- Ensure you ran
maturin developin the same environment you’re importing from.
- Ensure you ran
- Build/link errors on macOS (Xcode/SDK):
- Install Command Line Tools:
xcode-select --install.
- Install Command Line Tools:
OSErrorwhen callingload_file(...):- Check the path and file format (Turtle/N3). Use absolute paths when in doubt.
Contributing (Python bindings)
- Keep tests under
python/tests/minimal and representative. Prefer inputs fromexample_models/. - Format/lint Python with standard tooling; Rust code follows
cargo fmt/cargo clippy. - For broader project info (CLI, library, benchmarks), see the repository root
README.md.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file reasonable-0.3.3a4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: reasonable-0.3.3a4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 5.4 MB
- Tags: PyPy, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e73eaac84944bbb6ca9b702ce3b22ad0aa78ae321c7277185ca2013eee681a25
|
|
| MD5 |
937256c89204c735b3057433dcb014db
|
|
| BLAKE2b-256 |
d6790aef898424b4ed43f6ec112eaada65fd2f2eee0255927ee6e1bb8ef27a25
|
File details
Details for the file reasonable-0.3.3a4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: reasonable-0.3.3a4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 5.4 MB
- Tags: PyPy, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7301da4517e161e3d74374cb4152da108a252518d0e36118891c536cdf0c6664
|
|
| MD5 |
e9ce11ec918d92467ae55482f6ac5014
|
|
| BLAKE2b-256 |
c61a7f9d90e9c62a957f694b6c7e78bae8995924ba98f7f85e56bca2facc0190
|
File details
Details for the file reasonable-0.3.3a4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: reasonable-0.3.3a4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 5.4 MB
- Tags: CPython 3.12, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6a366b4e154cf5b3a283d9d33d71b9f806ca1a1d07251595b1db4b5952285c9f
|
|
| MD5 |
065313548fd010273eab04f49ec2c8ef
|
|
| BLAKE2b-256 |
5f25da3b3435bb028eca3d30d8432db9408dfc162ae2c9441886fd3b6126ce1f
|
File details
Details for the file reasonable-0.3.3a4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: reasonable-0.3.3a4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 5.4 MB
- Tags: CPython 3.11, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4630240e4f34bbee1c9dabf6b24f96ed61152c98edabaea910a5295542827595
|
|
| MD5 |
a6808f1ec130e6621bd0ebaea15d1c56
|
|
| BLAKE2b-256 |
d2efd2a8cd3daa904a5a6bcc6ba7f3719d1b594eb79232e71fa4d42fbe5e0006
|
File details
Details for the file reasonable-0.3.3a4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: reasonable-0.3.3a4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 5.4 MB
- Tags: CPython 3.10, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e8aef1f3369e9bd5aea1de5282e73709daf10bc4909b32ebf799c2b8bd048753
|
|
| MD5 |
e5f6151214256f629bbaba3f701d4bd6
|
|
| BLAKE2b-256 |
7950fb6bba862bd42b80a4c3c6a413c5d26b20075452cc9f8036666bfe5253b0
|
File details
Details for the file reasonable-0.3.3a4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: reasonable-0.3.3a4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 5.4 MB
- Tags: CPython 3.9, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
acdd5c21e8589dbe131a4235b8561d3d54404866654eb3fd1bc34489ba08de84
|
|
| MD5 |
5ba728f6fc9afbb398254536c99b9bf9
|
|
| BLAKE2b-256 |
2fe09cfc60241744bf651627f5c34126aef851cc125a61213b7196b62baadbe9
|
File details
Details for the file reasonable-0.3.3a4-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: reasonable-0.3.3a4-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 5.4 MB
- Tags: CPython 3.9+, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0051ac55d4891101d7d685421a0673b699491cffd140a3177ea4f36e953227d2
|
|
| MD5 |
74a05e2ed9b8527797e2a344e088ae47
|
|
| BLAKE2b-256 |
2732e7149fccac9eb485a6d6bd5e31d30055bcb96192c439f347a6e9ee8a25db
|
File details
Details for the file reasonable-0.3.3a4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: reasonable-0.3.3a4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 5.4 MB
- Tags: CPython 3.8, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
97346a2306ebed5519964febcc3926266f227aa73e37170f200e6ee18b4aedb3
|
|
| MD5 |
7ceb7b7213f20f93a27eb8c7fd61ec37
|
|
| BLAKE2b-256 |
c6a47b3fd123bf225d3fb4b4561766c167cbd89f3cb61b5c122efba4e0691561
|