Skip to main content

coordinode

PyPI Python License CI

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 -d or 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)
# 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) require majority here.
  • write_concern: "majority" (default) · a member count (1 leader only, 0 fire-and-forget) · WriteConcern(w, journal, timeout_ms) with journal one of journal (default) · cache · memory. The volatile cache and memory states are accepted only with w of 0 or 1.
  • read_preference: primary (default) · primary_preferred · secondary · secondary_preferred · nearest
  • vector_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. A vector_consistency hint in the query wins.
  • vector_build_wait_ms: how long a vector search waits for an index still being built; 0 refuses 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,
)
Package Description
langchain-coordinode LangChain GraphStore + GraphCypherQAChain
llama-index-graph-stores-coordinode LlamaIndex PropertyGraphStore

Support

USDT TRC-20

USDT (TRC-20), maintainer's personal wallet: TFDsezHa1cBkoeZT5q2T49Wp66K8t2DmdA

License

Apache-2.0

Metadata

Release files for coordinode 4.0.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 coordinode 4.0.1
File Size Uploaded Provenance
coordinode-4.0.1.tar.gz 101.1 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for coordinode 4.0.1
File Interpreter ABI Platform
coordinode-4.0.1-py3-none-any.whl Python 3 none any Details

Total release size: 246.8 kB

Release files / coordinode-4.0.1.tar.gz

Download URL coordinode-4.0.1.tar.gz
Size 101.1 kB
Tags Source
SHA-256 checksum
How to use checksums
80741505ba6fce52577e8c097e6e344f50f27a06c220de5864d8cda429bd646b
BLAKE2b-256 checksum
How to use checksums
8db8ba38051011db60d4c9b42be4ac640e59effef649bfaaa193ec650a298d85
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 17, 2026.

Transparency log

Release files / coordinode-4.0.1-py3-none-any.whl

Download URL coordinode-4.0.1-py3-none-any.whl
Size 145.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
311d4e817aae20f437e387ab4696384de43fd45896a1fca545552e9c83181390
BLAKE2b-256 checksum
How to use checksums
cacb5f3db13bf74e78eac44d3a5c88ece5f1b2ee40d3e7e8487773a8f87d51d4
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 17, 2026.

Transparency log

Security for coordinode 4.0.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.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for coordinode-4.0.1.tar.gz

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 17, 2026.

Transparency log

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