# ProllyTree Python Bindings
This directory contains Python bindings for the ProllyTree Rust library, providing a Pythonic interface to the probabilistic tree data structure.
## Building the Python Package
### Prerequisites
- Rust toolchain (1.70 or later)
- Python 3.8 or later
- `maturin` build tool
### Installation
1. Install maturin:
```bash
pip install maturin
```
2. Build and install the package in development mode:
```bash
cd /path/to/prollytree
maturin develop --features python
```
3. Or build a wheel for distribution:
```bash
maturin build --release --features python
```
## Usage Example
```python
from prollytree import ProllyTree, TreeConfig
# Create an in-memory tree
tree = ProllyTree(storage_type="memory")
# Insert key-value pairs
tree.insert(b"key1", b"value1")
tree.insert(b"key2", b"value2")
# Batch insert
items = [(b"key3", b"value3"), (b"key4", b"value4")]
tree.insert_batch(items)
# Find values
value = tree.find(b"key1") # Returns b"value1"
# Update a value
tree.update(b"key1", b"new_value1")
# Delete keys
tree.delete(b"key2")
# Get tree properties
print(f"Size: {tree.size()}")
print(f"Depth: {tree.depth()}")
print(f"Root hash: {tree.get_root_hash().hex()}")
# Generate and verify Merkle proofs
proof = tree.generate_proof(b"key3")
is_valid = tree.verify_proof(proof, b"key3", b"value3")
# Compare trees
tree2 = ProllyTree()
tree2.insert(b"key1", b"different_value")
diff = tree.diff(tree2)
# File-based storage
config = TreeConfig(base=4, modulus=64)
file_tree = ProllyTree(storage_type="file", path="/tmp/my_tree", config=config)
file_tree.insert(b"persistent_key", b"persistent_value")
file_tree.save_config()
```
## API Reference
### TreeConfig
Configuration class for ProllyTree:
- `base`: Base for the rolling hash (default: 4)
- `modulus`: Modulus for the rolling hash (default: 64)
- `min_chunk_size`: Minimum chunk size (default: 1)
- `max_chunk_size`: Maximum chunk size (default: 4096)
- `pattern`: Pattern for chunk boundaries (default: 0)
### ProllyTree
Main tree class with the following methods:
- `__init__(storage_type="memory", path=None, config=None)`: Create a new tree
- `insert(key: bytes, value: bytes)`: Insert a key-value pair
- `insert_batch(items: List[Tuple[bytes, bytes]])`: Batch insert
- `find(key: bytes) -> Optional[bytes]`: Find a value by key
- `update(key: bytes, value: bytes)`: Update an existing key
- `delete(key: bytes)`: Delete a key
- `delete_batch(keys: List[bytes])`: Batch delete
- `size() -> int`: Get number of key-value pairs
- `depth() -> int`: Get tree depth
- `get_root_hash() -> bytes`: Get the root hash
- `stats() -> Dict[str, int]`: Get tree statistics
- `generate_proof(key: bytes) -> bytes`: Generate a Merkle proof
- `verify_proof(proof: bytes, key: bytes, expected_value: Optional[bytes]) -> bool`: Verify a proof
- `diff(other: ProllyTree) -> Dict`: Compare two trees
- `traverse() -> str`: Get string representation of tree structure
- `save_config()`: Save tree configuration to storage
## Running Tests
```bash
cd python
python -m pytest tests/
```
## Running Examples
```bash
cd python
python examples/basic_usage.py
```
## Publishing to PyPI
### Prerequisites
1. **Get API Tokens**:
- TestPyPI: https://test.pypi.org/manage/account/token/
- PyPI: https://pypi.org/manage/account/token/
2. **Set Environment Variables**:
```bash
export MATURIN_PYPI_TOKEN="pypi-your-token-here"
# or for TestPyPI
export TEST_PYPI_API_TOKEN="pypi-your-test-token-here"
```
### Manual Publishing
1. **Test on TestPyPI first**:
```bash
./publish_python.sh test
```
2. **Publish to production PyPI**:
```bash
./publish_python.sh prod
```
### Automated Publishing (GitHub Actions)
The repository includes a GitHub Actions workflow that automatically builds and publishes to PyPI when you push a version tag:
```bash
# Create and push a version tag
git tag v0.2.1
git push origin v0.2.1
```
**Setup Required**:
1. Add `PYPI_API_TOKEN` to GitHub repository secrets
2. Configure PyPI trusted publishing (recommended) or use API tokens
### Version Management
Update version in `pyproject.toml` before publishing:
```toml
[project]
version = "0.2.1" # Update this
```
Raw data
{
"_id": null,
"home_page": null,
"name": "prollytree",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": "Feng Zhang <f.feng.zhang@gmail.com>",
"keywords": "prolly, tree, probabilistic, merkle, hash, data-structures, btree, merkle-tree",
"author": "Feng Zhang <f.feng.zhang@gmail.com>",
"author_email": "Feng Zhang <f.feng.zhang@gmail.com>",
"download_url": "https://files.pythonhosted.org/packages/13/89/e7b5ebd73a7333c3d6192c68c9c229215b3111a5ce79bb6a81ca90a24ed3/prollytree-0.2.1.tar.gz",
"platform": null,
"description": "# ProllyTree Python Bindings\n\nThis directory contains Python bindings for the ProllyTree Rust library, providing a Pythonic interface to the probabilistic tree data structure.\n\n## Building the Python Package\n\n### Prerequisites\n\n- Rust toolchain (1.70 or later)\n- Python 3.8 or later\n- `maturin` build tool\n\n### Installation\n\n1. Install maturin:\n```bash\npip install maturin\n```\n\n2. Build and install the package in development mode:\n```bash\ncd /path/to/prollytree\nmaturin develop --features python\n```\n\n3. Or build a wheel for distribution:\n```bash\nmaturin build --release --features python\n```\n\n## Usage Example\n\n```python\nfrom prollytree import ProllyTree, TreeConfig\n\n# Create an in-memory tree\ntree = ProllyTree(storage_type=\"memory\")\n\n# Insert key-value pairs\ntree.insert(b\"key1\", b\"value1\")\ntree.insert(b\"key2\", b\"value2\")\n\n# Batch insert\nitems = [(b\"key3\", b\"value3\"), (b\"key4\", b\"value4\")]\ntree.insert_batch(items)\n\n# Find values\nvalue = tree.find(b\"key1\") # Returns b\"value1\"\n\n# Update a value\ntree.update(b\"key1\", b\"new_value1\")\n\n# Delete keys\ntree.delete(b\"key2\")\n\n# Get tree properties\nprint(f\"Size: {tree.size()}\")\nprint(f\"Depth: {tree.depth()}\")\nprint(f\"Root hash: {tree.get_root_hash().hex()}\")\n\n# Generate and verify Merkle proofs\nproof = tree.generate_proof(b\"key3\")\nis_valid = tree.verify_proof(proof, b\"key3\", b\"value3\")\n\n# Compare trees\ntree2 = ProllyTree()\ntree2.insert(b\"key1\", b\"different_value\")\ndiff = tree.diff(tree2)\n\n# File-based storage\nconfig = TreeConfig(base=4, modulus=64)\nfile_tree = ProllyTree(storage_type=\"file\", path=\"/tmp/my_tree\", config=config)\nfile_tree.insert(b\"persistent_key\", b\"persistent_value\")\nfile_tree.save_config()\n```\n\n## API Reference\n\n### TreeConfig\n\nConfiguration class for ProllyTree:\n\n- `base`: Base for the rolling hash (default: 4)\n- `modulus`: Modulus for the rolling hash (default: 64)\n- `min_chunk_size`: Minimum chunk size (default: 1)\n- `max_chunk_size`: Maximum chunk size (default: 4096)\n- `pattern`: Pattern for chunk boundaries (default: 0)\n\n### ProllyTree\n\nMain tree class with the following methods:\n\n- `__init__(storage_type=\"memory\", path=None, config=None)`: Create a new tree\n- `insert(key: bytes, value: bytes)`: Insert a key-value pair\n- `insert_batch(items: List[Tuple[bytes, bytes]])`: Batch insert\n- `find(key: bytes) -> Optional[bytes]`: Find a value by key\n- `update(key: bytes, value: bytes)`: Update an existing key\n- `delete(key: bytes)`: Delete a key\n- `delete_batch(keys: List[bytes])`: Batch delete\n- `size() -> int`: Get number of key-value pairs\n- `depth() -> int`: Get tree depth\n- `get_root_hash() -> bytes`: Get the root hash\n- `stats() -> Dict[str, int]`: Get tree statistics\n- `generate_proof(key: bytes) -> bytes`: Generate a Merkle proof\n- `verify_proof(proof: bytes, key: bytes, expected_value: Optional[bytes]) -> bool`: Verify a proof\n- `diff(other: ProllyTree) -> Dict`: Compare two trees\n- `traverse() -> str`: Get string representation of tree structure\n- `save_config()`: Save tree configuration to storage\n\n## Running Tests\n\n```bash\ncd python\npython -m pytest tests/\n```\n\n## Running Examples\n\n```bash\ncd python\npython examples/basic_usage.py\n```\n\n## Publishing to PyPI\n\n### Prerequisites\n\n1. **Get API Tokens**:\n - TestPyPI: https://test.pypi.org/manage/account/token/\n - PyPI: https://pypi.org/manage/account/token/\n\n2. **Set Environment Variables**:\n ```bash\n export MATURIN_PYPI_TOKEN=\"pypi-your-token-here\"\n # or for TestPyPI\n export TEST_PYPI_API_TOKEN=\"pypi-your-test-token-here\"\n ```\n\n### Manual Publishing\n\n1. **Test on TestPyPI first**:\n ```bash\n ./publish_python.sh test\n ```\n\n2. **Publish to production PyPI**:\n ```bash\n ./publish_python.sh prod\n ```\n\n### Automated Publishing (GitHub Actions)\n\nThe repository includes a GitHub Actions workflow that automatically builds and publishes to PyPI when you push a version tag:\n\n```bash\n# Create and push a version tag\ngit tag v0.2.1\ngit push origin v0.2.1\n```\n\n**Setup Required**:\n1. Add `PYPI_API_TOKEN` to GitHub repository secrets\n2. Configure PyPI trusted publishing (recommended) or use API tokens\n\n### Version Management\n\nUpdate version in `pyproject.toml` before publishing:\n```toml\n[project]\nversion = \"0.2.1\" # Update this\n```\n",
"bugtrack_url": null,
"license": "Apache-2.0",
"summary": "Python bindings for ProllyTree - a probabilistic tree for efficient storage and retrieval",
"version": "0.2.1",
"project_urls": {
"Bug Tracker": "https://github.com/zhangfengcdt/prollytree/issues",
"Documentation": "https://docs.rs/prollytree",
"Homepage": "https://github.com/zhangfengcdt/prollytree",
"Repository": "https://github.com/zhangfengcdt/prollytree.git"
},
"split_keywords": [
"prolly",
" tree",
" probabilistic",
" merkle",
" hash",
" data-structures",
" btree",
" merkle-tree"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "553e870bf4365050be72dbb994d76067fb40d0f057f0150a7447870fa2af395f",
"md5": "18b7b08b86d5a1f9b7941d0f7ec84037",
"sha256": "08d9d1808faa420e39a52895404d5401894b90e54bd4f420c9d49fd6a7e14c55"
},
"downloads": -1,
"filename": "prollytree-0.2.1-cp311-cp311-macosx_11_0_arm64.whl",
"has_sig": false,
"md5_digest": "18b7b08b86d5a1f9b7941d0f7ec84037",
"packagetype": "bdist_wheel",
"python_version": "cp311",
"requires_python": ">=3.8",
"size": 467580,
"upload_time": "2025-07-19T20:09:48",
"upload_time_iso_8601": "2025-07-19T20:09:48.755648Z",
"url": "https://files.pythonhosted.org/packages/55/3e/870bf4365050be72dbb994d76067fb40d0f057f0150a7447870fa2af395f/prollytree-0.2.1-cp311-cp311-macosx_11_0_arm64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "1389e7b5ebd73a7333c3d6192c68c9c229215b3111a5ce79bb6a81ca90a24ed3",
"md5": "581c0b5763a24778fd0b92e7cf1d2f29",
"sha256": "efc4c4cc06bd968c658fe29d3f07c46d147b0ccadbebbd4c1749f36400fdaab7"
},
"downloads": -1,
"filename": "prollytree-0.2.1.tar.gz",
"has_sig": false,
"md5_digest": "581c0b5763a24778fd0b92e7cf1d2f29",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 136993,
"upload_time": "2025-07-19T20:09:51",
"upload_time_iso_8601": "2025-07-19T20:09:51.981198Z",
"url": "https://files.pythonhosted.org/packages/13/89/e7b5ebd73a7333c3d6192c68c9c229215b3111a5ce79bb6a81ca90a24ed3/prollytree-0.2.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-07-19 20:09:51",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "zhangfengcdt",
"github_project": "prollytree",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "prollytree"
}