coordinode
Python gRPC client for CoordiNode — the graph-native hybrid retrieval engine for AI and GraphRAG.
Installation
pip install coordinode
uv add coordinode
Requirements
- Python 3.11+
- Running CoordiNode instance (
docker compose up -dor binary)
Quick Start
from coordinode import CoordinodeClient
# Synchronous client — context manager handles connection lifecycle
with CoordinodeClient("localhost:7080") as db:
# Cypher query — returns List[Dict[str, Any]]
result = db.cypher("RETURN 1 AS n")
print(result) # [{'n': 1}]
# With parameters
rows = db.cypher(
"MATCH (n:Person {name: $name}) RETURN n.age AS age",
params={"name": "Alice"},
)
# Create nodes
db.cypher(
"CREATE (n:Document {title: $title, embedding: $vec})",
params={"title": "RAG intro", "vec": [0.1, 0.2, 0.3, 0.4]},
)
# Health check
assert db.health()
Async Client
import asyncio
from coordinode import AsyncCoordinodeClient
async def main():
async with AsyncCoordinodeClient("localhost:7080") as db:
rows = await db.cypher("MATCH (n:Concept) RETURN n.name AS name LIMIT 5")
for row in rows:
print(row["name"])
asyncio.run(main())
Connection Options
# host:port string
client = CoordinodeClient("localhost:7080")
# Separate host and port
client = CoordinodeClient("localhost", port=7080)
# TLS
client = CoordinodeClient("db.example.com:7443", tls=True)
# Custom timeout (seconds)
client = CoordinodeClient("localhost:7080", timeout=60.0)
Type Mapping
CoordiNode properties map to Python types automatically:
| Python type | CoordiNode type |
|---|---|
int |
int_value |
float |
float_value |
str |
string_value |
bool |
bool_value |
bytes |
bytes_value |
list[float] |
Vector (HNSW-indexable) |
list[Any] |
PropertyList |
dict[str, Any] |
PropertyMap |
None |
unset (null semantics) |
Vector Search
# Store a node with a vector embedding
db.cypher(
"CREATE (d:Doc {title: $title, embedding: $vec})",
params={"title": "RAG intro", "vec": [0.1] * 384},
)
# Nearest-neighbour search
results = db.vector_search(
label="Doc",
property="embedding",
vector=[0.1] * 384,
top_k=10,
metric="cosine", # "cosine" | "l2" | "dot" | "l1"
)
for r in results:
print(r.node.id, r.distance)
Hybrid Search (v0.4+)
Fuse BM25 full-text and vector similarity using Cypher scoring functions:
# Full-text scoring (text_score / text_match) requires a TEXT INDEX on the
# queried property — without it those calls return zero/no matches.
db.create_text_index("idx_doc_body", "Doc", "body")
# Reciprocal Rank Fusion of text + vector. Projecting `d AS doc_id` returns the
# internal node id (an integer) — fetch properties explicitly when needed.
rows = db.cypher(
"""
MATCH (d:Doc)
WHERE text_match(d, $q) OR d.embedding IS NOT NULL
RETURN d AS doc_id,
d.title AS title,
rrf_score(
text_score(d, $q),
vec_score(d.embedding, $vec)
) AS score
ORDER BY score DESC LIMIT 10
""",
params={"q": "graph neural network", "vec": [0.1] * 384},
)
# Full node properties: db.get_node(rows[0]["doc_id"]).
Helpers available in Cypher (evaluated server-side in coordinode-rs ≥ v0.4.0):
text_score, vec_score, doc_score, text_match, rrf_score,
hybrid_score. These are built-in Cypher functions; nothing to import on the
Python side.
ATTACH / DETACH DOCUMENT (v0.4+)
Promote a nested property to a graph node (and back):
db.cypher("MATCH (a:Article {id: $id}) DETACH DOCUMENT a.body AS (d:Body)", params={"id": 1})
db.cypher("MATCH (a:Article {id: $id})-[:HAS_BODY]->(d:Body) ATTACH DOCUMENT d INTO a.body", params={"id": 1})
Consistency Controls
# Majority read for strict freshness. `n AS node_id` returns the integer id;
# use get_node(id) or project explicit properties (e.g. n.email AS email).
db.cypher(
"MATCH (n:Account) RETURN n AS node_id, n.email AS email",
read_concern="majority",
)
# Writes default to a journaled majority. Weaken it explicitly per write,
# only for data that may be lost with its leader:
from coordinode import WriteConcern
db.cypher("CREATE (n:Hit {t: timestamp()})", write_concern=1) # leader only
db.cypher("CREATE (n:Hit {t: timestamp()})", write_concern=WriteConcern(w=1, journal="memory"))
# Causal read: see at least the state at raft index 42. The fence is about
# which replica may answer, so it is the READ concern that has to be majority.
db.cypher(
"MATCH (n) RETURN count(n) AS total",
after_index=42,
read_concern="majority",
)
# Write only if the node is still at the version you read.
node = db.get_node(node_id)
with db.transaction() as tx:
tx.cypher("MATCH (n) WHERE id(n) = $id SET n.seen = true", params={"id": node_id})
tx.commit(expect={node.id: node.version}) # ABORTED / REVISION_MISMATCH if it moved
# tx.commit_ts is when the write landed: at_timestamp=tx.commit_ts reads exactly it.
Accepted values:
read_concern:local(default) ·majority·linearizable·snapshot. Causal reads (after_index> 0) requiremajorityhere.write_concern:"majority"(default) · a member count (1leader only,0fire-and-forget) ·WriteConcern(w, journal, timeout_ms)withjournalone ofjournal(default) ·cache·memory. The volatilecacheandmemorystates are accepted only withwof 0 or 1.read_preference:primary(default) ·primary_preferred·secondary·secondary_preferred·nearestvector_consistency:current(the index as it is: fastest, may include writes newer than the read) ·snapshot(index candidates filtered at the read's snapshot) ·exact(every vector of the label, without the index). Omitted, the mode the read concern implies. Avector_consistencyhint in the query wins.vector_build_wait_ms: how long a vector search waits for an index still being built;0refuses a building index at once. Omitted, the server's default.
db.cypher(
"MATCH (d:Doc) RETURN d.title AS title ORDER BY vector_distance(d.embedding, $q) LIMIT 5",
params={"q": query_vector},
vector_consistency="exact",
vector_build_wait_ms=0,
)
Related Packages
| Package | Description |
|---|---|
langchain-coordinode |
LangChain GraphStore + GraphCypherQAChain |
llama-index-graph-stores-coordinode |
LlamaIndex PropertyGraphStore |
Links
Support
USDT (TRC-20), maintainer's personal wallet: TFDsezHa1cBkoeZT5q2T49Wp66K8t2DmdA
License
Apache-2.0
Metadata
Release files for coordinode 4.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| coordinode-4.0.0.tar.gz | 94.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| coordinode-4.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 233.3 kB
Release files / coordinode-4.0.0.tar.gz
| Download URL | coordinode-4.0.0.tar.gz |
|---|---|
| Size | 94.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
701b4e2e6c137c64261556e992a5543e4922e3aa9e53a10713efca06bd46db28
|
|
BLAKE2b-256 checksum How to use checksums |
b1f089837b1d41b094dc85e8164e31b8ef9aecab73b57def5ab22d706b31c825
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 7, 2026.
Transparency logRelease files / coordinode-4.0.0-py3-none-any.whl
| Download URL | coordinode-4.0.0-py3-none-any.whl |
|---|---|
| Size | 139.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
53c9bb72e1369ab07585b81ebc6775e9445b74faf2242f3d9b35b4ae32c3c985
|
|
BLAKE2b-256 checksum How to use checksums |
e536efe34e63519c58d04745a9b98706c103ad0e24d15e2bc9830f781d839874
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 7, 2026.
Transparency log