omop-graph is a lightweight, opinionated knowledge-graph traversal and path-analysis library built on top of the OMOP vocabulary model.
It provides:
- a stable KnowledgeGraph façade over OMOP concepts and relationships
- flexible graph traversal (forward, backward, bidirectional)
- path discovery with transparent scoring
- traceable explanations of traversal decisions
- multiple rendering backends (text, HTML, Mermaid)
The library is designed for:
- interactive analysis (Jupyter)
- reproducible research
- downstream tooling (NLP pipelines, ontology alignment, curation tools)
pip install omop-graphWith embedding support (sqlite-vec backend, zero config):
pip install "omop-graph[emb]"For larger deployments use [pgvector] or [faiss-cpu] instead (or in addition).
Full setup is covered in the omop-emb documentation.
KnowledgeGraph is the main entry point. It wraps a SQLAlchemy Engine connected to an OMOP vocabulary schema and provides a high-level Pythonic API over the relational tables.
from sqlalchemy import create_engine
from omop_graph.graph.kg import KnowledgeGraph
engine = create_engine("postgresql://user:pass@localhost/omop")
kg = KnowledgeGraph(engine)
# Lookup a concept by label
match_group = kg.label_lookup("Atrial Fibrillation", fuzzy=False)
concept = match_group.best_match
print(f"ID: {concept.concept_id}, Name: {concept.matched_label}")
# Traverse the hierarchy
parents = kg.parents(concept.concept_id)Nodes are OMOP Concepts; Edges are OMOP Concept_Relationships.
Relationships are pre-classified into semantic kinds (PredicateKind):
HIERARCHY— parent/child ontological relationshipsIDENTITY— mapping to standard conceptsCOMPOSITION— part-of relationshipsASSOCIATION— lateral clinical associationsATTRIBUTE— concept attribute relationships
This classification drives traversal filtering and scoring.
from omop_graph.graph.paths import find_shortest_paths
from omop_graph.extensions.omop_alchemy import PredicateKind
ingredient = kg.concept_id_by_code("RxNorm", "6809") # Metformin
drug = kg.concept_id_by_code("RxNorm", "860975") # Metformin 500 MG Oral Tablet
paths, trace = find_shortest_paths(
kg,
source=drug,
target=ingredient,
predicate_kinds=frozenset({PredicateKind.HIERARCHY, PredicateKind.IDENTITY}),
max_depth=6,
traced=True,
)Outputs can be rendered as plain text, HTML (Jupyter), or Mermaid diagrams. Rendering auto-detects the environment.
from IPython.display import HTML, display
from omop_graph.render import render_trace
display(HTML(render_trace(kg, trace)))omop_graph/
├── graph/ # graph logic, traversal, paths, scoring
├── render/ # HTML / text / Mermaid renderers
├── reasoning/ # ontology traversal methods for specific reasoner tasks
│ ├── resolvers/ # resolve labels via exact / fuzzy / full-text / synonym search
│ └── phenotypes/ # set operations for hierarchical groupings
├── oaklib_interface/ # OAK-compliant adapter
├── api.py # stable public API surface
└── db/ # session helpers