API Reference

This page contains the complete API reference for ProllyTree Python bindings.

Core Classes

ProllyTree - Python bindings for the Rust ProllyTree implementation

A Prolly Tree is a hybrid data structure that combines B-trees and Merkle trees to provide efficient data access with verifiable integrity.

class prollytree.ProllyTree(storage_type='memory', path=None, config=None)

Bases: object

delete(key)
delete_batch(keys)
depth()
diff(_other)
find(key)
generate_proof(key)
get_root_hash()
insert(key, value)
insert_batch(items)
save_config()
size()
stats()
traverse()
update(key, value)
verify_proof(proof_bytes, key, expected_value=None)
class prollytree.TreeConfig(base=4, modulus=64, min_chunk_size=1, max_chunk_size=4096, pattern=0)

Bases: object

class prollytree.VersionedKvStore(path, storage_backend=None)

Bases: object

branch(name)
checkout(branch_or_commit)
commit(message)
create_branch(name)
current_branch()
current_commit()

Get the current commit’s object ID

Returns:

The hexadecimal string representation of the current commit ID

Return type:

str

delete(key)
diff(from_ref, to_ref)

Compare two commits or branches and return all keys that are added, updated or deleted

Parameters:
  • from_ref – Reference (branch or commit) to compare from

  • to_ref – Reference (branch or commit) to compare to

Returns:

List of differences between the two references

Return type:

List[KvDiff]

generate_proof(key)
get(key)
get_commit_history()
get_commits_for_key(key)
get_keys_at_ref(reference)
insert(key, value)
list_branches()
list_keys()
log()
merge(source_branch, conflict_resolution=None)

Merge another branch into the current branch

Parameters:
  • source_branch – Name of the branch to merge from

  • conflict_resolution (default: None) – Strategy for resolving conflicts (default: IgnoreAll)

Returns:

The commit ID of the merge commit

Return type:

str

Raises:

ValueError – If merge fails, has unresolved conflicts, or storage backend doesn’t support merge

static open(path, storage_backend=None)
status()
storage_backend()
try_merge(source_branch)

Attempt to merge another branch and return any conflicts

Parameters:

source_branch – Name of the branch to merge from

Returns:

(success: bool, conflicts: List[MergeConflict])

If success is True, conflicts will be empty and merge was applied If success is False, conflicts contains unresolved conflicts and merge was not applied

Return type:

tuple

update(key, value)
verify_proof(proof_bytes, key, expected_value=None)
class prollytree.StorageBackend

Bases: object

File = StorageBackend.File
Git = StorageBackend.Git
InMemory = StorageBackend.InMemory
RocksDB = StorageBackend.RocksDB
class prollytree.MergeConflict

Bases: object

Python wrapper for MergeConflict

base_value
destination_value
key
source_value
class prollytree.ConflictResolution

Bases: object

Python enum for conflict resolution strategies

IgnoreAll = ConflictResolution.IgnoreAll
TakeDestination = ConflictResolution.TakeDestination
TakeSource = ConflictResolution.TakeSource
class prollytree.ProllySQLStore(path)

Bases: object

Python-exposed SQL store backed by ProllyTree.

# Async/Sync Bridge (Python ↔ Rust ↔ GlueSQL)

Python is single-threaded (GIL), Rust storage is synchronous, and GlueSQL requires an async runtime. The bridging pattern used here is:

  1. py.allow_threads() — releases the Python GIL so other Python threads can run while Rust executes.

  2. A per-call tokio::runtime::Runtime is created inside the GIL-free closure. A per-call runtime avoids lifetime issues with Python’s GIL management and is acceptable because Python-to-Rust calls are already coarse-grained.

  3. runtime.block_on(async { … }) drives the GlueSQL async execution, which internally uses spawn_blocking for the underlying sync store operations.

  4. Python::with_gil() re-acquires the GIL to construct Python return values.

```text Python call (GIL held)

└─ py.allow_threads (GIL released)
└─ tokio::runtime::Runtime::new()
└─ runtime.block_on(async { glue.execute(…).await })
└─ GlueSQL → ProllyStorage → spawn_blocking → sync store

└─ Python::with_gil() → return PyObject

```

commit(_message)
create_table(table_name, columns)
execute(query, format='dict')
execute_many(queries)
insert(table_name, values)
static open(path)
select(table_name, columns=None, where_clause=None)
class prollytree.WorktreeManager(repo_path)

Bases: object

add_worktree(path, branch, create_branch)
get_branch_commit(branch)

Get the current commit hash of a branch

is_locked(worktree_id)
list_branches()

List all branches in the repository

list_worktrees()
lock_worktree(worktree_id, reason)
merge_branch(source_worktree_id, target_branch, commit_message)

Merge a worktree branch to another target branch

merge_to_main(worktree_id, commit_message)

Merge a worktree branch back to main branch

remove_worktree(worktree_id)
unlock_worktree(worktree_id)
class prollytree.WorktreeVersionedKvStore

Bases: object

commit(message)
current_branch()
delete(key)
static from_worktree(worktree_path, worktree_id, branch, manager)
get(key)
insert(key, value)
is_locked()
list_keys()
lock(reason)
unlock()
worktree_id()
class prollytree.NamespacedKvStore(path)

Bases: object

branch(name)

Create a new branch and switch to it.

checkout(branch_or_commit)

Checkout a branch or commit.

commit(message=None)

Commit all staged changes across all namespaces.

current_branch

Get current branch name.

delete(key)

Delete from the default namespace.

delete_namespace(namespace)

Delete an entire namespace.

get(key)

Get from the default namespace.

get_namespace_root_hash(namespace)

Get the root hash for a namespace (O(1) lookup).

insert(key, value)

Insert into the default namespace.

list_keys()

List keys in the default namespace.

list_namespaces()

List all namespace names.

log()

Get commit history.

migrate_v1_to_v2()

Migrate a V1 (flat) store to V2 (namespaced) format.

namespace_changed(namespace, commit_a, commit_b)

Check if a namespace changed between two commits.

ns_delete(namespace, key)

Delete a key from a specific namespace.

ns_get(namespace, key)

Get a value by key from a specific namespace.

ns_insert(namespace, key, value)

Insert a key-value pair into a specific namespace.

ns_list_keys(namespace)

List all keys in a specific namespace.

static open(path)

Open an existing NamespacedKvStore (auto-detects V1/V2 format).

ProllyTree

class prollytree.ProllyTree(storage_type='memory', path=None, config=None)

Bases: object

delete(key)
delete_batch(keys)
depth()
diff(_other)
find(key)
generate_proof(key)
get_root_hash()
insert(key, value)
insert_batch(items)
save_config()
size()
stats()
traverse()
update(key, value)
verify_proof(proof_bytes, key, expected_value=None)

TreeConfig

class prollytree.TreeConfig(base=4, modulus=64, min_chunk_size=1, max_chunk_size=4096, pattern=0)

Bases: object

Versioned Storage

VersionedKvStore

class prollytree.VersionedKvStore(path, storage_backend=None)

Bases: object

branch(name)
checkout(branch_or_commit)
commit(message)
create_branch(name)
current_branch()
current_commit()

Get the current commit’s object ID

Returns:

The hexadecimal string representation of the current commit ID

Return type:

str

delete(key)
diff(from_ref, to_ref)

Compare two commits or branches and return all keys that are added, updated or deleted

Parameters:
  • from_ref – Reference (branch or commit) to compare from

  • to_ref – Reference (branch or commit) to compare to

Returns:

List of differences between the two references

Return type:

List[KvDiff]

generate_proof(key)
get(key)
get_commit_history()
get_commits_for_key(key)
get_keys_at_ref(reference)
insert(key, value)
list_branches()
list_keys()
log()
merge(source_branch, conflict_resolution=None)

Merge another branch into the current branch

Parameters:
  • source_branch – Name of the branch to merge from

  • conflict_resolution (default: None) – Strategy for resolving conflicts (default: IgnoreAll)

Returns:

The commit ID of the merge commit

Return type:

str

Raises:

ValueError – If merge fails, has unresolved conflicts, or storage backend doesn’t support merge

static open(path, storage_backend=None)
status()
storage_backend()
try_merge(source_branch)

Attempt to merge another branch and return any conflicts

Parameters:

source_branch – Name of the branch to merge from

Returns:

(success: bool, conflicts: List[MergeConflict])

If success is True, conflicts will be empty and merge was applied If success is False, conflicts contains unresolved conflicts and merge was not applied

Return type:

tuple

update(key, value)
verify_proof(proof_bytes, key, expected_value=None)

StorageBackend

class prollytree.StorageBackend

Bases: object

File = StorageBackend.File
Git = StorageBackend.Git
InMemory = StorageBackend.InMemory
RocksDB = StorageBackend.RocksDB

Merge Operations

MergeConflict

class prollytree.MergeConflict

Bases: object

Python wrapper for MergeConflict

base_value
destination_value
key
source_value

ConflictResolution

class prollytree.ConflictResolution

Bases: object

Python enum for conflict resolution strategies

IgnoreAll = ConflictResolution.IgnoreAll
TakeDestination = ConflictResolution.TakeDestination
TakeSource = ConflictResolution.TakeSource

SQL Support

ProllySQLStore

class prollytree.ProllySQLStore(path)

Bases: object

Python-exposed SQL store backed by ProllyTree.

# Async/Sync Bridge (Python ↔ Rust ↔ GlueSQL)

Python is single-threaded (GIL), Rust storage is synchronous, and GlueSQL requires an async runtime. The bridging pattern used here is:

  1. py.allow_threads() — releases the Python GIL so other Python threads can run while Rust executes.

  2. A per-call tokio::runtime::Runtime is created inside the GIL-free closure. A per-call runtime avoids lifetime issues with Python’s GIL management and is acceptable because Python-to-Rust calls are already coarse-grained.

  3. runtime.block_on(async { … }) drives the GlueSQL async execution, which internally uses spawn_blocking for the underlying sync store operations.

  4. Python::with_gil() re-acquires the GIL to construct Python return values.

```text Python call (GIL held)

└─ py.allow_threads (GIL released)
└─ tokio::runtime::Runtime::new()
└─ runtime.block_on(async { glue.execute(…).await })
└─ GlueSQL → ProllyStorage → spawn_blocking → sync store

└─ Python::with_gil() → return PyObject

```

commit(_message)
create_table(table_name, columns)
execute(query, format='dict')
execute_many(queries)
insert(table_name, values)
static open(path)
select(table_name, columns=None, where_clause=None)