Skip to main content

Lance Graph

A high-performance Cypher-capable graph query engine with Python bindings for building scalable, serverless knowledge graphs.

Lance Graph combines a Rust-powered Cypher query engine with Python APIs for:

  • Fast graph queries using Cypher query language
  • AI-powered knowledge extraction from text (via LLM)
  • Lance-backed storage for efficient graph data management
  • Natural language Q&A over your knowledge graphs
  • FastAPI web service for graph queries

Installation

pip install tf-lance-graph

Previously published as lance-graph by the upstream project (which is no longer maintained). This fork's releases are published under tf-lance-graph; the Python import name remains lance_graph.

Quick Start

1. Simple Cypher Query

import pyarrow as pa
from lance_graph import CypherQuery, GraphConfig

cfg = (
    GraphConfig.builder()
    .with_node_label("Person", "id")
    .with_node_label("City", "id")
    .with_relationship("lives_in", "src", "dst")
    .build()
)

datasets = {
    "Person": pa.table({"id": [1, 2], "name": ["Alice", "Bob"]}),
    "City": pa.table({"id": [10, 20], "name": ["London", "Sydney"]}),
    "lives_in": pa.table({"src": [1, 2], "dst": [10, 20]}),
}

query = """
    MATCH (p:Person)-[:lives_in]->(c:City)
    RETURN p.name, c.name
"""

result = CypherQuery(query).with_config(cfg).execute(datasets)
print(result.to_pylist())

[{'p.name': 'Alice', 'c.name': 'London'}, {'p.name': 'Bob', 'c.name': 'Sydney'}]

2. Multi-Query Execution with CypherEngine

For executing multiple queries against the same datasets, use CypherEngine to cache the catalog and achieve better performance:

import pyarrow as pa
from lance_graph import CypherEngine, GraphConfig

cfg = (
    GraphConfig.builder()
    .with_node_label("Person", "id")
    .with_node_label("City", "id")
    .with_relationship("lives_in", "src", "dst")
    .build()
)

datasets = {
    "Person": pa.table({"id": [1, 2], "name": ["Alice", "Bob"], "age": [30, 25]}),
    "City": pa.table({"id": [10, 20], "name": ["London", "Sydney"]}),
    "lives_in": pa.table({"src": [1, 2], "dst": [10, 20]}),
}

# Create engine once - builds catalog
engine = CypherEngine(cfg, datasets)

# Execute multiple queries efficiently - catalog is reused
result1 = engine.execute("MATCH (p:Person) WHERE p.age > 25 RETURN p.name")
result2 = engine.execute("MATCH (p:Person)-[:lives_in]->(c:City) RETURN p.name, c.name")
result3 = engine.execute("MATCH (p:Person) RETURN count(*) as total")

print(result1.to_pylist())
# [{'p.name': 'Alice'}]

3. Direct SQL Queries

For data analytics workflows where you prefer standard SQL over Cypher, use SqlQuery or SqlEngine. No GraphConfig is needed — write explicit JOINs against your tables directly:

import pyarrow as pa
from lance_graph import SqlQuery, SqlEngine

person = pa.table({
    "id": [1, 2, 3],
    "name": ["Alice", "Bob", "Carol"],
    "age": [28, 34, 29],
})
knows = pa.table({"src_id": [1, 1, 2], "dst_id": [2, 3, 3]})
datasets = {"person": person, "knows": knows}

# One-off query
result = SqlQuery(
    "SELECT p.name, p.age FROM person p WHERE p.age > 30"
).execute(datasets)
print(result.to_pylist())
# [{'name': 'Bob', 'age': 34}]

# Multi-query with cached context
engine = SqlEngine(datasets)
r1 = engine.execute("SELECT COUNT(*) AS cnt FROM person")
r2 = engine.execute(
    "SELECT p1.name AS person, p2.name AS friend "
    "FROM person p1 "
    "JOIN knows k ON p1.id = k.src_id "
    "JOIN person p2 ON p2.id = k.dst_id"
)

4. Unity Catalog Integration

Connect to Unity Catalog (OSS) to discover and query Delta Lake or Parquet tables without manually loading data:

from lance_graph import UnityCatalog

# Connect to Unity Catalog
uc = UnityCatalog("http://localhost:8080/api/2.1/unity-catalog")

# Browse catalog hierarchy
catalogs = uc.list_catalogs()
schemas = uc.list_schemas("unity")
tables = uc.list_tables("unity", "default")

# Inspect table metadata
table = uc.get_table("unity", "default", "marksheet")
print(table.data_source_format)  # "Delta"
print(table.columns())           # [{"name": "id", "type_name": "INT", ...}, ...]

# Auto-register all tables and query via SQL
engine = uc.create_sql_engine("unity", "default")
result = engine.execute("SELECT * FROM marksheet WHERE mark > 80")
print(result.to_pandas())

For tables on cloud storage (S3, Azure, GCS):

uc = UnityCatalog(
    "http://localhost:8080/api/2.1/unity-catalog",
    storage_options={
        "azure_storage_account_name": "myaccount",
        "azure_storage_account_key": "...",
    }
)
engine = uc.create_sql_engine("unity", "default")

5. Build a Knowledge Graph from Text

from pathlib import Path
from knowledge_graph import (
    KnowledgeGraphConfig,
    LanceKnowledgeGraph,
    LanceGraphStore,
    get_extractor,
)
from knowledge_graph.cli.ingest import extract_and_add

# Initialize knowledge graph
config = KnowledgeGraphConfig.from_root(Path("./my_graph"))
config.ensure_directories()

# Create schema
schema_path = config.resolved_schema_path()
if not schema_path.exists():
    schema_content = """
nodes:
  Entity:
    id_field: entity_id

relationships:
  RELATIONSHIP:
    source: source_entity_id
    target: target_entity_id
"""
    schema_path.write_text(schema_content, encoding="utf-8")

store = LanceGraphStore(config)
store.ensure_layout()

graph_config = config.load_graph_config()
kg = LanceKnowledgeGraph(graph_config, storage=store)
kg.ensure_initialized()

# Extract and add entities/relationships from text
# Using heuristic extractor for testing without API key
extractor = get_extractor("heuristic")
# or using LLM extractor (requires API key)
# extractor = get_extractor("llm", llm_model="gpt-4o-mini")
text = """
Albert Einstein developed the theory of relativity at Princeton.
Marie Curie discovered radioactivity in Paris.
"""

extract_and_add(text, kg, extractor, embedding_generator=None)

# Query the graph
result = kg.query("""
    MATCH (e:Entity)
    RETURN e.name, e.entity_type
    LIMIT 10
""")
print(result.to_pylist())

6. Natural Language Q&A

from knowledge_graph.llm.qa import ask_question

# Ask questions in natural language
answer = ask_question(
    "Who discovered radioactivity?",
    kg,
    llm_model="gpt-4o-mini"
)
print(answer)
# Output: Marie Curie discovered radioactivity.

Command-Line Interface

Lance Graph includes a CLI for building and querying knowledge graphs:

# Initialize and extract
knowledge_graph --root ./my_graph --init
knowledge_graph --root ./my_graph --extract-and-add notes.txt

# Query with Cypher
knowledge_graph --root ./my_graph "MATCH (e:Entity) RETURN e.name LIMIT 10"

# Natural language Q&A
knowledge_graph --root ./my_graph --ask "Who discovered DNA?"

For complete CLI documentation and examples, see the main README.

Requirements

  • Python 3.11+
  • Optional: OpenAI API key for LLM extraction

Contributing

Lance Graph is open source! Contributions are welcome.

Quick start

cd python
uv venv --python 3.11 .venv
source .venv/bin/activate
uv pip install maturin[patchelf]
uv pip install -e '.[tests]'
maturin develop
pytest python/tests/ -v

Development workflow

For linting and type checks:

# Install dev dependencies
uv pip install -e '.[dev]'

# Run linters and type checker
ruff format python/              # format code
ruff check python/               # lint code
pyright                          # type check

# Run specific tests
pytest python/tests/test_graph.py::test_basic_node_selection -v

# Rebuild extension after Rust changes
maturin develop

If another virtual environment is already active, run deactivate (or unset VIRTUAL_ENV) before invoking uv run so uv binds to .venv.

Repository layout

  • crates/lance-graph-python/src/ – PyO3 bridge that exposes graph APIs to Python
  • python/python/lance_graph/ – pure-Python wrapper and __init__
  • python/python/knowledge_graph/ – CLI, FastAPI, and extractor utilities built on Lance
  • python/python/tests/ – graph-centric functional tests

For more information on development setup, building from source, running tests, and code quality guidelines, see DEVELOPMENT.md.

License

Apache 2.0

Metadata

Release files for tf-lance-graph 0.6.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for tf-lance-graph 0.6.1
File Size Uploaded Provenance
tf_lance_graph-0.6.1.tar.gz 259.9 kB Without provenance Details

Built distributions (wheels)

Table of built distributions (wheels) for tf-lance-graph 0.6.1
File Interpreter ABI Platform
tf_lance_graph-0.6.1-cp39-abi3-manylinux_2_39_x86_64.whl CPython 3.9 abi3 Linux glibc 2.39+ x86-64 Details
tf_lance_graph-0.6.1-cp39-abi3-manylinux_2_39_aarch64.whl CPython 3.9 abi3 Linux glibc 2.39+ ARM64 Details
tf_lance_graph-0.6.1-cp39-abi3-macosx_11_0_arm64.whl CPython 3.9 abi3 macOS 11.0+ ARM64 Details

Total release size: 198.8 MB

Release files / tf_lance_graph-0.6.1.tar.gz

Download URL tf_lance_graph-0.6.1.tar.gz
Size 259.9 kB
Tags Source
SHA-256 checksum
How to use checksums
0d72fbc54c730f855efab9c13d5b0b3e1b6a5034d6a822fd99dee032b5507f1f
BLAKE2b-256 checksum
How to use checksums
5e9cfad04a5c3e624cc4abbab0abf69e19a1371b19307934bfff233337ad0050
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.17 {"installer":{"name":"uv","version":"0.12.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / tf_lance_graph-0.6.1-cp39-abi3-manylinux_2_39_x86_64.whl

Download URL tf_lance_graph-0.6.1-cp39-abi3-manylinux_2_39_x86_64.whl
Size 69.7 MB
Tags CPython 3.9 Linux glibc 2.39+ x86-64 abi3
SHA-256 checksum
How to use checksums
f1d16838fe6abdc414294781df42b7e7388342c22812fee71c46b0b23a6d1075
BLAKE2b-256 checksum
How to use checksums
7cab61851bed058acf1ac14f547d8367e669c3df8b9b550e422a3ba30940c47d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.17 {"installer":{"name":"uv","version":"0.12.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / tf_lance_graph-0.6.1-cp39-abi3-manylinux_2_39_aarch64.whl

Download URL tf_lance_graph-0.6.1-cp39-abi3-manylinux_2_39_aarch64.whl
Size 67.8 MB
Tags CPython 3.9 Linux glibc 2.39+ ARM64 abi3
SHA-256 checksum
How to use checksums
d6a5c09d5dc6dcbc87e4382aff8cf3e081c583aef954210ae57abd9b4485e4ba
BLAKE2b-256 checksum
How to use checksums
4c96f7dc0790a65cef07dc4fa8796503ff0fcb6a78ae6ba85f339315e5ee3275
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.17 {"installer":{"name":"uv","version":"0.12.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / tf_lance_graph-0.6.1-cp39-abi3-macosx_11_0_arm64.whl

Download URL tf_lance_graph-0.6.1-cp39-abi3-macosx_11_0_arm64.whl
Size 61.0 MB
Tags CPython 3.9 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
19b5ecd0d9af524b9133379771d77876ad519e331fa635ef639508add42345b4
BLAKE2b-256 checksum
How to use checksums
0c93e2e49636cc720ee80aae3254045b9dcc90c35d6879fe9f037d449fc9f8b3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.17 {"installer":{"name":"uv","version":"0.12.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Security for tf-lance-graph 0.6.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page