rumo reads tabular data and runs rules on it.
It uses the nemo rule engine.
rumo has three parts:
- A Rust library.
- A command-line tool with the name
rumo. - A Python package with the name
pyrumo.
With rumo, you can:
- Show the structure of a table.
- Convert a table to RDF in the Turtle format.
- Run nemo rules on a pandas DataFrame, a Polars DataFrame or RDF data.
- Get the results as a pandas DataFrame, a Polars DataFrame or a list of dictionaries.
The full manual is in the docs directory. Refer to Documentation.
pip install pyrumoTo use pandas DataFrames, install the pandas extra:
pip install "pyrumo[pandas]"Each GitHub release has prebuilt binaries for Linux (x86_64, aarch64), Windows (x86_64) and macOS (x86_64, aarch64).
To build from the source code, use this command:
cargo install --path . --features rulesThe nemo rule engine needs the nightly Rust toolchain.
The file rust-toolchain.toml selects this toolchain automatically.
import pandas as pd
from pyrumo import Rumo
df = pd.read_csv("examples/sample.csv")
rules = """
@prefix : <http://example.org/> .
good(?name, ?score) :- data(?r, :name, ?name), data(?r, :score, ?s),
?score = DOUBLE(?s), ?score > $GOOD_SCORE .
"""
rumo = Rumo(rules=rules, data=df, predicate="data")
results = rumo.run(params={"GOOD_SCORE": 90})
print(results.to_pandas("good"))The output is:
name score
0 Bob 92.0
1 Dave 95.1
A Rumo object keeps one rule program and the data for the rules.
- Load the rules from a string (
rules=orread_rules_str) or from a file (rules_file=orread_rules_file). - Load the data. The data can be:
- A pandas DataFrame or a Polars DataFrame (
data=orread_dataframe). - RDF data as a string (
data="..."orread_data_str). - A data file (
data_file=orread_data_file).
- A pandas DataFrame or a Polars DataFrame (
- Run the rules with
run(params=..., predicates=...). - Read the results from the
RumoResultsobject.
Rumo converts each DataFrame to Turtle.
Each row becomes a subject (:r0, :r1, …).
Each column becomes a property (:name, :age, …).
Rumo keeps the data in memory with a resource name.
The default resource name is data.ttl. For a data file, it is the file name.
There are two methods to connect the data to the rules:
-
Set
predicate="data".Rumothen adds@import data :- turtle { resource = "data.ttl" } .to the rules. -
Use the resource name in your own
@importstatement. For example, this runsexamples/sample.rlswithout changes:rumo = Rumo(rules_file="examples/sample.rls", data=df, resource="sample.ttl")
params gives values for the global parameters of the rules, for example $GOOD_SCORE:
| Python value | nemo value |
|---|---|
int, float |
Number |
bool |
Boolean |
str |
String |
str with the form "<http://...>" |
IRI |
If you do not set predicates, run returns the @output and @export predicates of the rules.
If the rules have no such predicates, run returns all calculated predicates.
| Method | Returns |
|---|---|
to_pandas(p) |
A pandas DataFrame. |
to_polars(p) |
A Polars DataFrame. |
to_dicts(p) |
A list of dictionaries. |
rows(p) |
A list of tuples. |
to_dict() |
A dictionary with all predicates. |
results["p"] |
A list of dictionaries. |
You can omit p if the results have only one predicate.
The column names are the variable names in the rule heads.
For example, good(?name, ?score) gives the columns name and score.
To set different names, use columns=[...].
Refer to examples/run_rules.py for a full example.
import polars as pl
import pyrumo
df = pl.read_csv("examples/sample.csv")
print(pyrumo.describe(df))
print(pyrumo.to_turtle(df, "http://example.org/", "r"))Refer to examples/describe_dataframe.py for a full example.
Show the structure of a CSV file:
rumo describe --data examples/sample.csvConvert a CSV file to Turtle:
rumo convert --data examples/sample.csv --result-format turtleRun a rule file:
rumo rules --rules examples/sample.rls --data examples/sample.csv --param GOOD_SCORE=90| File | Description |
|---|---|
examples/sample.csv |
A sample CSV file. |
examples/sample.ttl |
The sample CSV file as Turtle. |
examples/sample.rls |
A sample nemo rule file. |
examples/describe_dataframe.py |
Shows the structure of a DataFrame in Python. |
examples/run_rules.py |
Runs rules on a pandas DataFrame in Python. |
The manual uses mdBook.
The source files are in docs/src.
To read the manual:
- Install mdBook:
cargo install mdbook. - Build and open the manual:
mdbook serve docs --open.
The Docs workflow publishes the manual to GitHub Pages when docs/ changes on the main branch.
Before the first publication, set Settings → Pages → Source to GitHub Actions.
The manual is written in Simplified Technical English.
To build and test the Python extension:
python3 -m venv .venv
source .venv/bin/activate
pip install maturin
maturin develop --extras test
pytestTo run the Rust tests:
cargo test
cargo test --features rules- Change
versioninCargo.toml. This is also the version of the Python package. - Run
cargo checkto updateCargo.lock. - Commit and push these changes.
- Publish a GitHub release. The tag must be the version with a
vbefore it, for examplev0.2.0.
The Binaries workflow attaches the command-line archives to the release.
The Python workflow publishes the pyrumo wheels to PyPI.
Each workflow first compares the tag with the version in Cargo.toml.
If they are different, the workflow stops before it builds.
If the check fails, do these steps:
- Delete the GitHub release.
- Delete the tag:
git push --delete origin v0.2.0. - Change the version in
Cargo.toml, then commit and push. - Publish the release again.
MIT