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.

Release files for polypack-db 3.3.2

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.3.2
File Interpreter ABI Platform
polypack_db-3.3.2-cp38-abi3-win_amd64.whl CPython 3.8 abi3 Windows x86-64 Details
polypack_db-3.3.2-cp38-abi3-manylinux_2_34_x86_64.whl CPython 3.8 abi3 Linux glibc 2.34+ x86-64 Details
polypack_db-3.3.2-cp38-abi3-macosx_11_0_arm64.whl CPython 3.8 abi3 macOS 11.0+ ARM64 Details

Total release size: 2.2 MB

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

Download URL polypack_db-3.3.2-cp38-abi3-win_amd64.whl
Size 662.0 kB
Tags CPython 3.8 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
b30e1f737712a04e26cf3b8ed5926424988d3ae1b9c4fa497b7ed8df6c8688f0
BLAKE2b-256 checksum
How to use checksums
8af7517046eee6047a0c78010cc50ecfc8f0e921b031192cc19dad12ada230cd
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 Aug 23, 2026.

Transparency log

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

Download URL polypack_db-3.3.2-cp38-abi3-manylinux_2_34_x86_64.whl
Size 831.7 kB
Tags CPython 3.8 Linux glibc 2.34+ x86-64 abi3
SHA-256 checksum
How to use checksums
201d06b8d3ba6e158fa9b9f724e0ac3699527194939a8c73717a4dde8b115777
BLAKE2b-256 checksum
How to use checksums
0e8e79acf0979b4f2aabfe18d0d06047f31b13149bebaf6c1ba77c7309f52196
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 Aug 23, 2026.

Transparency log

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

Download URL polypack_db-3.3.2-cp38-abi3-macosx_11_0_arm64.whl
Size 750.1 kB
Tags CPython 3.8 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
af15bc4ba4c39f9eda2d2d21268b57f12aca63eddb581bb1f73010fea3001887
BLAKE2b-256 checksum
How to use checksums
a4f19e15c1d8d54f147cf00f436051d977358e591b4ceeecbd3703b70a4b9e19
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 Aug 23, 2026.

Transparency log

Release history Release notifications | RSS feed

3.4.1

3 release files

3.4.0

3 release files

This release

3.3.2 This release

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