Skip to main content

polypack (Python)

Python bindings for the polypack embedded property-graph and vector-search core. PolyGraph and GraphQuery are a Python layer mirroring the TypeScript PolyGraph/GraphQuery API; vector indexing, persisted queries, and directory-backed persistence run in the Rust core (polypack._core, built from crates/polypack-python). Simple hot-cache filters, ordering, pagination, and aggregates use the local Python pipeline to avoid repeatedly serializing the working set across the Python/Rust boundary.

Install

pip install polypack-db

Requires Python 3.8+ and numpy. Prebuilt wheels are published from polypack-db on PyPI; the version tracks the TypeScript package and polypack-core crate in lockstep.

Quick start

import time
from polypack import PolyGraph

graph = PolyGraph()

graph.add_node({
    "id": "doc_1",
    "type": "document",
    "data": {"title": "Quantum Computing"},
    "vector": [0.95, 0.20, 0.10],
    "insertedAt": int(time.time() * 1000),
    "updatedAt": int(time.time() * 1000),
})

graph.add_edge("doc_1", "REFERENCES", "doc_2", ownership="owned")

# Search by similarity
graph.query() \
    .where_type("document") \
    .similar_to([0.90, 0.30, 0.10], 0.5, 5) \
    .to_list()

# Filter, traverse, aggregate
graph.query().where("title", "Quantum Computing").traverse("REFERENCES", 3).to_list()
graph.query().where_type("book").aggregate("price", "avg")

For directory-backed stores, use graph.query_persisted() for filters, ordering, pagination, and counts. These operations execute in the native store and only materialize the requested result page in Python:

graph.query_persisted().where_type("book").order_by("price", "desc").limit(20).to_list()

query_persisted() requires an open directory-backed store and returns a PersistedGraphQuery. Its supported chainable methods are:

  • where_type(*types)
  • where(field, value)
  • where_range(field, above=None, below=None) with exclusive boundaries
  • order_by(field, direction="asc")
  • offset(n) and limit(n)

Its terminal methods are synchronous: to_list(), ids(), and count(). to_list() returns only the requested page, while count() counts all records matching the filters before pagination. Pending writable changes are saved before a persisted query runs. Similarity, joins, and traversal remain on the hot GraphQuery API.

Python API surface

The main public classes are:

  • PolyGraph: graph lifecycle, mutations, transactions, persistence, and hot queries.
  • GraphQuery: synchronous hot-cache filters, ranges, ordering, pagination, traversal, joins, similarity, activation, and aggregates.
  • PersistedGraphQuery: native storage-level filtering, ordering, pagination, and counting for directory-backed stores.
  • ExactIndex and HnswIndex: standalone native vector indexes.
  • ActivationEngine: adaptive-memory operations over a PolyGraph.

Python method names use snake_case equivalents of the TypeScript API, such as add_node, update_node, where_type, similar_to, and to_list.

Persistence

PolyGraph.open(directory) attaches a directory-backed binary store (snapshot + write-ahead log, shared format with the TypeScript BinaryStoreAdapter) and loads any existing state. Use it as a context manager so the store is compacted and closed on exit:

with PolyGraph.open("./data") as graph:
    graph.add_node({...})
    graph.save()  # persists queued puts and deletions

Activation (adaptive memory)

Nodes can carry durable activation state that persists through the store. Reinforcement decay-corrects the prior state, adds a delta, and re-anchors the decay clock; reads decay lazily as a pure function of elapsed time:

from polypack import PolyGraph, ActivationEngine

graph = PolyGraph()
graph.add_node({"id": "a", "type": "doc", "data": {}, "insertedAt": 1, "updatedAt": 1})
graph.reinforce_node("a", 0.6, "user_read")      # durable, persisted
graph.reinforce_node("a", 0.3, "user_read", context="project-x")  # also reinforces a context
graph.suppress_node("outdated", 1.0, "stale")    # durable inhibition
graph.get_activation("a")                         # ~0.6, decay-corrected
graph.top_activated(5)                            # working-memory primitive

engine = ActivationEngine(graph)
engine.bump_attention("a", 0.2)                  # local, never serialized
engine.spread(["a"], depth=2, decay=0.5)         # relational spreading activation
engine.pulse([1.0, 0.0, ...])                    # semantic region scoring (vector)
engine.absorb([1.0, 0.0, ...])                   # pulse + reinforce above threshold
engine.working_memory(5)                         # current "mental state"
engine.working_memory(limit=8, token_budget=2000, diversity_lambda=0.5)  # budgeted + diverse
engine.working_memory(context="project-x", context_fallback=True)  # context lens with global fallback
engine.working_memory_persisted(limit=8, token_budget=2000)  # rank cold persisted nodes
engine.score_breakdown_of(graph.get_node("a"), 0.8, 0.2)  # explain pulse score
engine.set_weights({"semantic": 1.2})  # restore application-persisted feedback weights
engine.record_feedback("a", was_useful=True)     # nudge pulse's scoring weights

graph.query().where_activated(0.4) and graph.query().order_by_activation() filter/order by current activation. merge_activation and decay_factor are exposed for parity with the TypeScript/Rust implementations.

Nodes also support memory classes (episodic/semantic/procedural/entity, set via register_node_type(type, memory_class=...) as a type default or memoryClass on the node itself, driving differentiated decay half-lives) and confidence/provenance fields (confidence, source, observedAt, derivedFrom, supersedes, contradicts) — ordinary node fields, not activation state. graph.supersede(id, superseded_id) records a contradiction (suppresses the superseded node without deleting it) and graph.consolidate(node, source_ids) promotes a group of nodes into a higher-level one, both while keeping the sources in the graph. See docs/API.md for full parameter details.

save() writes the complete current graph and flushes any deletions recorded since the last save. close_store() — and exiting the with block, which calls it — saves any unsaved changes first, then compacts and closes; you don't need to call save() yourself before it, though doing so periodically (as above) still bounds how much a single close has to write and how much a crash before that could lose.

Vector indexes

ExactIndex and HnswIndex wrap the Rust vector core directly and can be used standalone, independent of PolyGraph:

from polypack import ExactIndex, HnswIndex

index = ExactIndex(distance="cosine")
index.add("doc_1", [0.95, 0.20, 0.10])
index.query([0.90, 0.30, 0.10], top_k=5, threshold=0.5)

approx = HnswIndex(m=16, ef_search=200)
approx.add_many([("doc_1", [0.95, 0.20, 0.10]), ("doc_2", [0.10, 0.90, 0.05])])

Errors

Native errors surface as PolypackError subclasses: PolypackValueError, PolypackDimensionError, PolypackClosedError, PolypackVersionError, PolypackCorruptDataError, and PolypackStorageError.

Development

See the top-level CONTRIBUTING.md for building the native extension with maturin and running the Python test suite.

Metadata

Release files for polypack-db 3.5.0

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

Built distributions (wheels)

Table of built distributions (wheels) for polypack-db 3.5.0
File Interpreter ABI Platform
polypack_db-3.5.0-cp38-abi3-win_amd64.whl CPython 3.8 abi3 Windows x86-64 Details
polypack_db-3.5.0-cp38-abi3-manylinux_2_34_x86_64.whl CPython 3.8 abi3 Linux glibc 2.34+ x86-64 Details
polypack_db-3.5.0-cp38-abi3-macosx_11_0_arm64.whl CPython 3.8 abi3 macOS 11.0+ ARM64 Details

Total release size: 2.4 MB

Release files / polypack_db-3.5.0-cp38-abi3-win_amd64.whl

Download URL polypack_db-3.5.0-cp38-abi3-win_amd64.whl
Size 710.6 kB
Tags CPython 3.8 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
4c195f38d06565f70ea05c435759b48c865a921a9a6f6143817fe1bbd74620b7
BLAKE2b-256 checksum
How to use checksums
c82e58fba2d82656b3530f1ef67d6b24eb1a06b5c0a3149274a3a2d06e870115
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 3, 2026.

Transparency log

Release files / polypack_db-3.5.0-cp38-abi3-manylinux_2_34_x86_64.whl

Download URL polypack_db-3.5.0-cp38-abi3-manylinux_2_34_x86_64.whl
Size 872.9 kB
Tags CPython 3.8 Linux glibc 2.34+ x86-64 abi3
SHA-256 checksum
How to use checksums
fd7dc576730a3661d74e834f7a458ced81b192e493bdfa0d5acaf1f026625a1f
BLAKE2b-256 checksum
How to use checksums
cd3ce84f5a2d677f3ffa97a682c265187f6fb101ed967aa19fe9c667669ea7d6
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 3, 2026.

Transparency log

Release files / polypack_db-3.5.0-cp38-abi3-macosx_11_0_arm64.whl

Download URL polypack_db-3.5.0-cp38-abi3-macosx_11_0_arm64.whl
Size 793.9 kB
Tags CPython 3.8 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
082bfcda4267cce47d32061f0db514a775c07a6c7280b63cd15030ed340afb64
BLAKE2b-256 checksum
How to use checksums
d600cf468b28a699b8c1916021f5234dfcacb1510cdd10e0754aaf3e5eebdc63
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 3, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

3.5.0 This release

3 release files

3.4.2

3 release files

3.4.1

3 release files

3.4.0

3 release files

3.3.2

3 release files

3.3.1

3 release files

3.3.0

3 release files

3.2.0

3 release files

3.1.0

3 release files

3.0.1

3 release files

3.0.0

3 release files

2.5.0

3 release files

2.4.7

3 release files

2.4.6

3 release files

2.4.5

3 release files

2.4.3

3 release files

2.4.2

3 release files

0.1.1

3 release files

0.1.0

3 release files

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