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-graphby the upstream project (which is no longer maintained). This fork's releases are published undertf-lance-graph; the Python import name remainslance_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(orunset VIRTUAL_ENV) before invokinguv runso uv binds to.venv.
Repository layout
crates/lance-graph-python/src/– PyO3 bridge that exposes graph APIs to Pythonpython/python/lance_graph/– pure-Python wrapper and__init__python/python/knowledge_graph/– CLI, FastAPI, and extractor utilities built on Lancepython/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
Links
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)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| tf_lance_graph-0.6.1.tar.gz | 259.9 kB | Without provenance | Details |
Built distributions (wheels)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| 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.