Open Knowledge Graphs and Ontologies plugin for mloda.
Project description
open-kgo
Open Knowledge Graphs and Ontologies plugin for mloda: nine connector families covering the knowledge-graph landscape, from SPARQL endpoints to SBOMs to agent memory, all behind one declarative Feature interface. Every connector and demo runs offline against in-memory libraries or committed fixtures. No Docker, no network.
At a glance
| Section | What you'll find |
|---|---|
| Quickstart | Run a SPARQL query against a shipped sample file in under a minute |
| The nine connector families | The core of this repo: a 9-family KG connector taxonomy with two plugins each |
| Semantic Fields — Layer 2 | Continuous, schema-grounded entity scoring via DC circuit model |
| Demos | Marimo notebooks and evaluation harnesses, all offline |
| Data and acknowledgments | Where the sample data comes from |
| Development setup | uv, tox, and the individual checks |
| Related repositories and documentation | mloda core, the plugin registry, and development guides |
Quickstart
Install the connectors from PyPI and run a SPARQL query against a small Turtle file:
pip install "open-kgo[kg-all]"
(Working from a clone instead? uv sync --extra kg-all, see Development setup.)
from pathlib import Path
from mloda.user import DataAccessCollection, Feature, Options, mloda
# Importing the plugin module registers the rdflib_sparql feature group.
import open_kgo.feature_groups.kg.rdf.rdflib_sparql # noqa: F401
from open_kgo.compute_frameworks.python_dict_kg_framework import KgPythonDictFramework
# Point at any RDF file. Here: a three-triple sample written on the spot.
ttl = Path("sample.ttl")
ttl.write_text(
"@prefix foaf: <http://xmlns.com/foaf/0.1/> .\n"
"@prefix ex: <http://example.org/> .\n"
"ex:alice foaf:knows ex:bob .\n"
"ex:bob foaf:knows ex:carol .\n"
)
feature = Feature(
"rdflib_sparql__knows",
options=Options(context={
"query_text": "PREFIX foaf: <http://xmlns.com/foaf/0.1/> "
"SELECT ?s ?o WHERE { ?s foaf:knows ?o }",
}),
)
partitions = mloda.run_all(
[feature],
compute_frameworks={KgPythonDictFramework},
data_access_collection=DataAccessCollection(
credentials=[{"rdflib_sparql": {"locator": str(ttl), "result_limit": 100}}],
),
)
for partition in partitions:
for row in partition:
print(row[feature.name])
Swap rdflib_sparql for any of the nine connector families below: same Feature to mloda.run_all shape, different reader.
The nine connector families
open_kgo/feature_groups/kg/ ships a connector taxonomy derived from a 103-system survey. Each family is a shared reader and feature-group base plus two concrete plugins running against in-memory libraries or local file fixtures:
| Family | What it connects to | Concrete plugins |
|---|---|---|
network_pg |
Property-graph databases with a vendor query language (Neo4j, Memgraph, Neptune, ...) | KuzuCypherReader, GrandCypherReader |
rdf |
RDF triple stores queried with SPARQL | RdfLibSparqlReader, OxigraphSparqlReader |
embedded |
In-process graph libraries with no network endpoint | NetworkxEmbeddedReader, IGraphEmbeddedReader |
rest_public |
Public REST (non-SPARQL) KG APIs (OpenAlex, ConceptNet, STRING, ...) | FileFixtureRestReader, FileFixturePagedRestReader |
lineage |
Metadata and data-lineage graphs (dbt, OpenLineage, DataHub, ...) | DbtManifestReader, OpenLineageReader |
code_build |
Code, build, and SBOM dependency graphs (CycloneDX, SPDX, ...) | CycloneDxSbomReader, SpdxSbomReader |
saas_authz |
SaaS and authorization tuple stores (OpenFGA, SpiceDB, Microsoft Graph, ...) | InProcessTupleStoreReader, PaginatedTupleStoreReader |
agent_memory |
LLM agent memory and GraphRAG graphs (Letta, Zep, Mem0, ...) | NetworkxMemoryReader, GraphWalkMemoryReader |
citation_rest |
Citation and scientific REST APIs (Reactome, OpenAlex citations, ...) | FileFixtureCitationReader, PaginatedCitationReader |
See open_kgo/feature_groups/kg/README.md for the full family map, the plugin anatomy, and what the prototype does and does not validate.
Install all KG extras with: pip install "open-kgo[kg-all]" (from a clone: uv sync --extra kg-all).
One feature per call. KG readers dispatch a single feature per load: every reader rejects a multi-feature
FeatureSetrather than silently labelling all rows with one feature name. Request features individually (oneFeaturepermloda.run_allslot) rather than batchingNof them into a single reader call.
No-Docker testing policy. Every connector test runs against rdflib, networkx, kuzu (embedded), or file fixtures. No Docker, no external services, no network calls.
Semantic Fields — Layer 2
The connector families (Layer 1 validation) answer: "is this traversal valid?" — binary yes/no.
SemanticField (Layer 2) answers: "how relevant is this entity to my query?" — a continuous score, grounded in DC electrical circuit theory.
The knowledge graph is modelled as a resistor network. Ontology-declared relationship weights become conductances. A query is expressed as two anchor nodes — a source (high voltage) and a sink (low voltage, ground). The solver finds the electric potential at every entity via the conductance-weighted graph Laplacian, then scores each entity by the current it carries between source and sink.
Why current? Current only flows through entities that bridge both anchors. An entity connected to only one side floats to that side's extreme voltage — zero potential difference, zero current, automatically excluded. No relation-type filtering needed; the circuit topology enforces the AND constraint.
from open_kgo.feature_groups.kg.ontology import SemanticField
# AND query: Sci-Fi films by Nolan
scores = SemanticField.compute_and(
namespace="metaqa",
edges=subgraph_edges, # 2-hop neighbourhood of both anchors
source={"Nolan": 1.0}, # high-voltage anchor
sink={"Sci-Fi": 0.0}, # ground
)
# → {"Interstellar": 0.394, "Inception": 0.312, "Dark Knight": 0.0, ...}
Relationship weights are declared in the ontology YAML and flow directly into the solver as conductances:
relationships:
directed_by: { domain: Movie, range: Person, weight: 0.9 }
has_genre: { domain: Movie, range: Genre, weight: 0.7 }
has_tags: { domain: Movie, range: Tag, weight: 0.2 }
The solver is pure Python (no numpy) with an optional numba JIT kernel that gives a 70× speedup at ~5 000-node subgraphs; it falls back silently when numba is absent.
| Layer | What it does | Status |
|---|---|---|
| L1 — OntologyRegistry | Binary valid/invalid edge checks, YAML-declared | Built |
| L2 — SemanticField | Continuous entity scoring via DC circuit model | Built |
| L3 — Discovery Engine | Guided multi-hop traversal by field strength | Planned |
Install: pip install "open-kgo[kg-semantic-field]" (from a clone: uv sync --extra kg-semantic-field)
Full visual explainer: demo/semantic_field_explainer.html — open in any browser, no server needed.
Demos
Three marimo notebooks plus two evaluation harnesses live under demo/:
demo/demo_kg_connectors.py: surface tour of all 9 families against the shipped fixtures.demo/demo_kg_build_repo.py: builds an RDF graph from this repo (filesystemrepo:contains+ Pythonrepo:imports), serializes to Turtle, and runs five SPARQL queries throughRdfLibSparqlReaderviamloda.run_all.demo/demo_kg_ontology.py: walks the ontology layer end to end.demo/demo_semantic_field.py: SemanticField Layer 2 — interactive director + genre query against MetaQA, with live scoring.demo/semantic_field_explainer.html: full visual explainer for SemanticField — circuit diagram, layer stack, why EM, 1/2/multi-hop examples, test results. Open in any browser.demo/eval_arch1_vs_arch2.pyanddemo/eval_qa_accuracy.py: evaluation harnesses comparing plain traversal vs. ontology-guided traversal.
Install the demo extras and open any notebook:
uv sync --extra demo
marimo edit demo/demo_kg_connectors.py
Every demo runs offline against a small committed sample graph: no download, no network, no external services.
Data and acknowledgments
The ontology demo and the two evaluation harnesses run against a small
hand-authored sample of public movie facts (demo/data/sample_kb.txt) written
in the triple format of the MetaQA dataset (Zhang, Yuyu et al., "Variational
Reasoning for Question Answering with Knowledge Graph", AAAI 2018,
https://github.com/yuyuz/MetaQA). The sample is committed in this repo and is
not derived from the MetaQA dataset files. The notebooks call
demo.data.ensure_data() at startup, which builds the sample subgraph offline.
To run against the full MetaQA benchmark (licensed under
CC BY 3.0, not
redistributed here), see demo/data/README.md.
Development setup
Install uv (if not already installed):
curl -LsSf https://astral.sh/uv/install.sh | sh
Create virtual environment and install dependencies:
uv venv
source .venv/bin/activate
uv sync --all-extras
Run all checks with tox:
uv tool install tox --with tox-uv
tox
Run individual checks
pytest
ruff format --check --line-length 120 .
ruff check .
mypy --strict --ignore-missing-imports .
bandit -c pyproject.toml -r -q .
Related repositories and documentation
- mloda: The core library for open data access. Declaratively define what data you need, not how to get it. See mloda.ai for an overview and business context and the documentation for detailed guides.
- mloda-registry: The central hub for discovering and sharing mloda plugins.
- Plugin development guides: How to build FeatureGroups, ComputeFrameworks, and Extenders.
- Claude Code skills: Assisted plugin development for Claude Code users.
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 Distribution
Built Distribution
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 open_kgo-0.2.2.tar.gz.
File metadata
- Download URL: open_kgo-0.2.2.tar.gz
- Upload date:
- Size: 115.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.20
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d583b9f73153388840dd1273206c49250735c61df25a501951f5b829d4b40588
|
|
| MD5 |
159cc5da0e342cb910dc11b38112c670
|
|
| BLAKE2b-256 |
304d6c491fec454c58fd14ba141829110946c110bde3ccc572e80afb3d34ac3b
|
File details
Details for the file open_kgo-0.2.2-py3-none-any.whl.
File metadata
- Download URL: open_kgo-0.2.2-py3-none-any.whl
- Upload date:
- Size: 143.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.20
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
db698c75d25462c0f9a06a941f6238d436a16b554afbabe369f7d00da2304fa5
|
|
| MD5 |
927fc0b4a2560e9a3ec4caccf0741645
|
|
| BLAKE2b-256 |
26041052585516b4c0f7f127639cecc0012c0e052f4204b590dba896b3356ff3
|