py-hamt 3.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,49 @@
1
+ name: Deploy static site generated by pdoc to GitHub Pages
2
+
3
+ on:
4
+ push:
5
+ branches: ["main"]
6
+
7
+ permissions:
8
+ contents: read
9
+ pages: write
10
+ id-token: write
11
+
12
+ jobs:
13
+ build:
14
+ environment:
15
+ name: github-pages
16
+ url: ${{ steps.deployment.outputs.page_url }}
17
+
18
+ permissions:
19
+ contents: read
20
+ pages: write
21
+ id-token: write
22
+
23
+ runs-on: ubuntu-latest
24
+
25
+ steps:
26
+ - name: Checkout
27
+ uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
28
+
29
+ - name: Setup Pages
30
+ uses: actions/configure-pages@983d7736d9b0ae728b81ab479565c72886d7745b # v5
31
+
32
+ - name: Install uv
33
+ uses: astral-sh/setup-uv@6b9c6063abd6010835644d4c2e1bef4cf5cd0fca # v6
34
+ with:
35
+ version: "latest"
36
+
37
+ - name: Create project environment
38
+ run: uv sync
39
+
40
+ - name: Build with pdoc
41
+ run: uv run pdoc py_hamt -o ./_site
42
+
43
+ - name: Upload artifact
44
+ # Automatically uploads an artifact from the './_site' directory by default
45
+ uses: actions/upload-pages-artifact@56afc609e74202658d3ffba0e8f6dda462b719fa # v3
46
+
47
+ - name: Deploy to GitHub Pages
48
+ id: deployment
49
+ uses: actions/deploy-pages@d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e # v4
@@ -0,0 +1,54 @@
1
+ name: Run checks
2
+ run-name: Triggered on push from ${{ github.actor }} to branch/tag ${{ github.ref_name }}
3
+ on: push
4
+
5
+ jobs:
6
+ validate:
7
+ runs-on: ubuntu-latest
8
+ steps:
9
+ - uses: actions/checkout@v4
10
+ - uses: actions/setup-python@v5
11
+ with:
12
+ python-version: "3.12"
13
+ - uses: pre-commit/action@v3.0.1
14
+ test:
15
+ name: Create project environment, run all checks
16
+ needs:
17
+ - validate
18
+ runs-on: ubuntu-latest
19
+ strategy:
20
+ fail-fast: true
21
+ matrix:
22
+ python-version: ["3.12"]
23
+ steps:
24
+ - name: Check out repository
25
+ uses: actions/checkout@v4
26
+ - name: Set up python ${{ matrix.python-version }}
27
+ uses: actions/setup-python@v5
28
+ with:
29
+ python-version: ${{ matrix.python-version }}
30
+
31
+ - name: Install uv
32
+ uses: astral-sh/setup-uv@6b9c6063abd6010835644d4c2e1bef4cf5cd0fca # v6
33
+ with:
34
+ version: "latest"
35
+
36
+ - name: Create project environment
37
+ run: uv sync
38
+
39
+ - name: Install IPFS
40
+ uses: oduwsdl/setup-ipfs@e92fedca9f61ab9184cb74940254859f4d7af4d9 # v0.6.3
41
+ with:
42
+ ipfs_version: "0.35.0"
43
+ run_daemon: true
44
+
45
+ - name: Run pytest with coverage
46
+ run: uv run pytest --ipfs --cov=py_hamt tests/ --cov-report=xml
47
+
48
+ - name: Upload coverage reports to Codecov
49
+ uses: codecov/codecov-action@18283e04ce6e62d37312384ff67231eb8fd56d24 # v5
50
+ with:
51
+ token: ${{ secrets.CODECOV_TOKEN }}
52
+
53
+ - name: Check coverage
54
+ run: uv run coverage report --fail-under=100 --show-missing
@@ -0,0 +1,159 @@
1
+ .DS_Store
2
+ pyrightconfig.json
3
+
4
+ *.prof
5
+ memray*
6
+
7
+ # Byte-compiled / optimized / DLL files
8
+ __pycache__/
9
+ *.py[cod]
10
+ *$py.class
11
+
12
+ # C extensions
13
+ *.so
14
+
15
+ # Distribution / packaging
16
+ .Python
17
+ build/
18
+ develop-eggs/
19
+ dist/
20
+ downloads/
21
+ eggs/
22
+ .eggs/
23
+ lib/
24
+ lib64/
25
+ parts/
26
+ sdist/
27
+ var/
28
+ wheels/
29
+ share/python-wheels/
30
+ *.egg-info/
31
+ .installed.cfg
32
+ *.egg
33
+ MANIFEST
34
+
35
+ # PyInstaller
36
+ # Usually these files are written by a python script from a template
37
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
38
+ *.manifest
39
+ *.spec
40
+
41
+ # Installer logs
42
+ pip-log.txt
43
+ pip-delete-this-directory.txt
44
+
45
+ # Unit test / coverage reports
46
+ htmlcov/
47
+ .tox/
48
+ .nox/
49
+ .coverage
50
+ .coverage.*
51
+ .cache
52
+ nosetests.xml
53
+ coverage.xml
54
+ *.cover
55
+ *.py,cover
56
+ .hypothesis/
57
+ .pytest_cache/
58
+ cover/
59
+
60
+ # Translations
61
+ *.mo
62
+ *.pot
63
+
64
+ # Django stuff:
65
+ *.log
66
+ local_settings.py
67
+ db.sqlite3
68
+ db.sqlite3-journal
69
+
70
+ # Flask stuff:
71
+ instance/
72
+ .webassets-cache
73
+
74
+ # Scrapy stuff:
75
+ .scrapy
76
+
77
+ # Sphinx documentation
78
+ docs/_build/
79
+
80
+ # PyBuilder
81
+ .pybuilder/
82
+ target/
83
+
84
+ # Jupyter Notebook
85
+ .ipynb_checkpoints
86
+
87
+ # IPython
88
+ profile_default/
89
+ ipython_config.py
90
+
91
+ # pyenv
92
+ # For a library or package, you might want to ignore these files since the code is
93
+ # intended to run in multiple environments; otherwise, check them in:
94
+ # .python-version
95
+
96
+ # pipenv
97
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
98
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
99
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
100
+ # install all needed dependencies.
101
+ #Pipfile.lock
102
+
103
+ # poetry
104
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
105
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
106
+ # commonly ignored for libraries.
107
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
108
+ #poetry.lock
109
+
110
+ # pdm
111
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
112
+ #pdm.lock
113
+ # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
114
+ # in version control.
115
+ # https://pdm.fming.dev/#use-with-ide
116
+ .pdm.toml
117
+
118
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
119
+ __pypackages__/
120
+
121
+ # Celery stuff
122
+ celerybeat-schedule
123
+ celerybeat.pid
124
+
125
+ # SageMath parsed files
126
+ *.sage.py
127
+
128
+ # Environments
129
+ .env
130
+ .venv
131
+ env/
132
+ venv/
133
+ ENV/
134
+ env.bak/
135
+ venv.bak/
136
+
137
+ # Spyder project settings
138
+ .spyderproject
139
+ .spyproject
140
+
141
+ # Rope project settings
142
+ .ropeproject
143
+
144
+ # mkdocs documentation
145
+ /site
146
+
147
+ # mypy
148
+ .mypy_cache/
149
+ .dmypy.json
150
+ dmypy.json
151
+
152
+ # Pyre type checker
153
+ .pyre/
154
+
155
+ # pytype static type analyzer
156
+ .pytype/
157
+
158
+ # Cython debug symbols
159
+ cython_debug/
@@ -0,0 +1,32 @@
1
+ repos:
2
+ - repo: https://github.com/compilerla/conventional-pre-commit
3
+ rev: v4.0.0
4
+ hooks:
5
+ - id: conventional-pre-commit
6
+ stages: [commit-msg]
7
+ - repo: https://github.com/pre-commit/pre-commit-hooks
8
+ rev: v5.0.0
9
+ hooks:
10
+ - id: check-ast
11
+ - id: check-case-conflict
12
+ - id: check-merge-conflict
13
+ - id: check-toml
14
+ - id: debug-statements
15
+ - id: end-of-file-fixer
16
+ - id: mixed-line-ending
17
+ - id: trailing-whitespace
18
+ - repo: https://github.com/charliermarsh/ruff-pre-commit
19
+ rev: v0.11.11
20
+ hooks:
21
+ - id: ruff-check
22
+ - id: ruff-format
23
+ - repo: https://github.com/ariebovenberg/slotscheck
24
+ rev: v0.17.1
25
+ hooks:
26
+ - id: slotscheck
27
+ name: slotscheck
28
+ entry: bash -c 'env PYTHONPATH=src slotscheck'
29
+ - repo: https://github.com/pre-commit/mirrors-mypy
30
+ rev: "v1.15.0"
31
+ hooks:
32
+ - id: mypy
@@ -0,0 +1 @@
1
+ 3.12
@@ -0,0 +1,127 @@
1
+ # Project Agents.md Guide for py-hamt
2
+
3
+ This AGENTS.md file provides comprehensive guidance for OpenAI Codex and other AI agents working with this codebase.
4
+
5
+ ## Project Description
6
+
7
+ This library is a python implementation of a HAMT, inspired by [rvagg's IAMap project written in JavaScript](https://github.com/rvagg/iamap).
8
+
9
+ py-hamt provides efficient storage and retrieval of large sets of key-value mappings in a content-addressed storage system. The main target is IPFS, and the data model used is IPLD.
10
+
11
+ dClimate primarily created this for storing large [zarrs](https://zarr.dev/) on IPFS. To see this in action, see our [data ETLs](https://github.com/dClimate/etl-scripts).
12
+
13
+ ## Project Architecture
14
+
15
+ A user instantiates a ContentAddressedStore such as KuboCAS which is then used to instantiate a HAMT. This HAMT can then be passed to a ZarrHAMTStore to read/write zarr files. An IPFS daemon running locally can be used or a remote one can be accessed via gateway(reads) & rpc endpoints(writes) on their IPFS defaults. For tests, a local docker container is spun up if docker is available.
16
+
17
+ ## Project Structure for OpenAI Codex Navigation
18
+
19
+ - `/py_hamt`: Source code of the py-hamt library
20
+ - `encryption_hamt_store.py` - Example using total encryption
21
+ - `hamt.py`- where the HAMT data structure is constructed and accesed
22
+ - `store.py`- Where various stores live that writes the data. Primarily used KuboCAS
23
+ - `zarr_hamt_store.py` - ZarrHAMTStore class used to directly write or read zarrs leveraging the HAMT data structure onto a Store usually a Content Addressed store like KuboCAS located in store.py.
24
+ - `/tests`: Test files that should be maintained and extended where possible.
25
+
26
+ ## Coding Conventions
27
+
28
+ ### General Conventions for AGENTS.md Implementation
29
+
30
+ - Use the latest version of Python (3.12) for all new code generated by OpenAI Codex
31
+ - The AI Agent should follow the existing code style in each file
32
+ - Agents.md requires meaningful variable and function names
33
+ - The AI Agent should add comments for complex logic as guided by Agents.md
34
+
35
+ ### Python Guidelines
36
+ - Use functional easy to understand functions wherever possible.
37
+ - All functions need to be fully typed with mypy.
38
+ - All functions require tests to be written and coverage must be full.
39
+ - Example usage can be found in the `/tests` folder
40
+
41
+ ### Development Setup
42
+
43
+ `py-hamt` uses uv for package management. If uv is not already present which can be checked with `uv` then it can be installed via
44
+
45
+ `curl -LsSf https://astral.sh/uv/install.sh | sh`
46
+
47
+ otherwise if uv is already present you can run
48
+
49
+ `uv sync` to install all dependencies
50
+
51
+ and then
52
+
53
+ `source .venv/bin/activate` to activate the venv created by uv.
54
+
55
+ Lastly while still setting up you can run
56
+
57
+ ```
58
+ pre-commit install
59
+ ```
60
+
61
+ to ensure pre-commit installed.
62
+
63
+ Docker is also used for integration tests to test ipfs. Try to have docker installed to be able to run all tests with` pytest --ipfs`
64
+
65
+ ## Testing Requirements for the Agent
66
+
67
+ All tests should be created within the `/tests` directory.
68
+
69
+ The agent should run tests with the following commands:
70
+
71
+ ```bash
72
+ # Run all tests
73
+ pytest --ipfs
74
+
75
+ # Run specific test file
76
+ pytest test tests/<insert_file_here>
77
+
78
+ # Run tests with coverage
79
+ pytest --ipfs --cov
80
+
81
+ # If IPFS is not present use
82
+ pytest --cov
83
+ ```
84
+
85
+ Tests should be kept as closed to 100% as possible.
86
+
87
+ ## Pull Request Guidelines for the Agent
88
+
89
+ When the Agent helps create a PR, please ensure it:
90
+
91
+ 1. Includes a clear description of the changes as guided by AGENTS.md
92
+ 2. References any related issues that the Agent is addressing
93
+ 3. Ensures all tests pass for code generated by the Agent
94
+ 4. Keeps PRs focused on a single concern as specified in AGENTS.md
95
+
96
+ ## Programmatic Checks for the Agent
97
+
98
+ Before submitting changes generated by the Agent, run:
99
+
100
+ ```bash
101
+ bash run-checks.sh
102
+ ```
103
+
104
+ **Note:** This assumes ipfs is running as `run-checks.sh` runs with the ``--ipfs` flag. If kubo ipfs is not running in a local daemon or docker was unable to instantiate simply run
105
+
106
+ ```
107
+ pytest --cov
108
+ ```
109
+
110
+ and
111
+
112
+ ```
113
+ uv run pre-commit run --all-files --show-diff-on-failure
114
+ ```
115
+
116
+ instead.
117
+
118
+
119
+ If there is an error with formatting for ruff and it can be autofixed you can normally run
120
+
121
+ ```
122
+ uv run ruff check --fix
123
+ ```
124
+
125
+ to fix it.
126
+
127
+ All checks must pass before the Agent generated code can be merged. AGENTS.md helps ensure the Agent follows these requirements.
@@ -0,0 +1,213 @@
1
+ # py-hamt Library Architecture Analysis
2
+
3
+ ## Overview
4
+
5
+ The py-hamt library is a Python implementation of a Hash Array Mapped Trie (HAMT) designed for content-addressed storage systems like IPFS. It provides efficient storage and retrieval of large key-value mappings using the IPLD data model.
6
+
7
+ ## Core Architecture
8
+
9
+ ### 1. HAMT Structure (`hamt.py`)
10
+
11
+ The core HAMT implementation follows a hierarchical trie structure where:
12
+ - **Nodes** contain 256 buckets (indexed 0-255)
13
+ - Each bucket can either be:
14
+ - A dictionary containing key-value mappings (when bucket size ≤ max_bucket_size)
15
+ - A link to a child Node (when bucket overflows)
16
+ - Hash values are consumed 8 bits at a time to determine bucket indices
17
+
18
+ #### Key Components:
19
+
20
+ **Node Class** (`hamt.py:62`)
21
+ - Fixed array of 256 elements representing buckets
22
+ - Uses `list[IPLDKind]` where empty dicts `{}` represent empty buckets
23
+ - Links are stored as single-element lists `[link_id]`
24
+ - Serializes to DAG-CBOR format for content addressing
25
+
26
+ **HAMT Class** (`hamt.py:287`)
27
+ - Main interface for trie operations
28
+ - Supports both read-only and read-write modes
29
+ - Uses asyncio locks for thread safety in write mode
30
+ - Implements two node storage strategies via NodeStore abstraction
31
+
32
+ ### 2. Storage Abstraction (`store.py`)
33
+
34
+ **ContentAddressedStore** (`store.py:11`)
35
+ - Abstract base class for content-addressed storage backends
36
+ - Returns immutable IDs (IPLDKind) for stored content
37
+ - Two codec types: "raw" for data, "dag-cbor" for structured content
38
+
39
+ **KuboCAS** (`store.py:74`)
40
+ - IPFS implementation using Kubo daemon
41
+ - Uses RPC API for writes (`/api/v0/add`)
42
+ - Uses HTTP Gateway for reads (`/ipfs/{cid}`)
43
+ - Supports authentication and custom headers
44
+ - Implements connection pooling and concurrency limiting
45
+
46
+ **InMemoryCAS** (`store.py:37`)
47
+ - Testing implementation using in-memory dictionary
48
+ - Content-addressed via Blake3 hashing
49
+
50
+ ### 3. Node Storage Strategies
51
+
52
+ **ReadCacheStore** (`hamt.py:150`)
53
+ - Used in read-only mode
54
+ - Implements LRU-style caching of loaded nodes
55
+ - Cannot perform writes (throws exception)
56
+ - Optimized for concurrent read operations
57
+
58
+ **InMemoryTreeStore** (`hamt.py:180`)
59
+ - Used in read-write mode
60
+ - Maintains modified nodes in memory buffer
61
+ - Uses UUID4 integers as temporary node IDs
62
+ - Implements sophisticated flush algorithm during `vacate()`
63
+
64
+ ### 4. Zarr Integration (`zarr_hamt_store.py`)
65
+
66
+ **ZarrHAMTStore** (`zarr_hamt_store.py:11`)
67
+ - Implements Zarr v3 Store interface
68
+ - Provides metadata caching for `zarr.json` files
69
+ - Supports directory listing operations with efficient prefix matching
70
+ - Key insight: Zarr keys map directly to HAMT keys without transformation
71
+
72
+ **SimpleEncryptedZarrHAMTStore** (`encryption_hamt_store.py:12`)
73
+ - Extends ZarrHAMTStore with ChaCha20-Poly1305 encryption
74
+ - Encrypts all data including metadata
75
+ - Uses 24-byte nonces and 16-byte authentication tags
76
+
77
+ ## Value Setting Mechanism & Data Flow
78
+
79
+ ### Setting Values (`_set_pointer` in `hamt.py:505`)
80
+
81
+ 1. **Hash and Navigate**: Key is hashed, bits extracted to determine path
82
+ 2. **Queue-based Insertion**: Uses FIFO queue to handle bucket overflows
83
+ 3. **Bucket Overflow Handling**: When bucket exceeds max_bucket_size:
84
+ - All existing items moved to queue for reinsertion
85
+ - New child node created and linked
86
+ - Continues insertion process at deeper level
87
+ 4. **Tree Rebalancing**: After insertion, `_reserialize_and_link` updates all affected nodes
88
+
89
+ ### Getting Values (`_get_pointer` in `hamt.py:618`)
90
+
91
+ 1. **Hash Traversal**: Follow hash-determined path through trie
92
+ 2. **Bucket Search**: Check final bucket for key
93
+ 3. **Pointer Resolution**: Return content-addressed pointer
94
+ 4. **Value Retrieval**: Load actual value from CAS using pointer
95
+
96
+ ### Memory Management
97
+
98
+ **Read-Write Mode**:
99
+ - Uses `InMemoryTreeStore` with UUID-based temporary IDs
100
+ - Modified nodes stay in memory until `make_read_only()` or `cache_vacate()`
101
+ - Flush algorithm uses DFS to preserve parent-child relationships
102
+
103
+ **Read-Only Mode**:
104
+ - Switches to `ReadCacheStore` for better read performance
105
+ - Allows concurrent operations without locks
106
+ - Cache size can be monitored and manually vacated
107
+
108
+ ## Architecture Gotchas & Edge Cases
109
+
110
+ ### 1. Mode Switching Complexity
111
+ - **Problem**: HAMT can switch between read-only and read-write modes
112
+ - **Gotcha**: In read-write mode, `root_node_id` is invalid until `make_read_only()`
113
+ - **Why**: InMemoryTreeStore uses temporary UUIDs that aren't content-addressed
114
+ - **Solution**: Always call `make_read_only()` before reading `root_node_id`
115
+
116
+ ### 2. Thread Safety Limitations
117
+ - **Problem**: Only async-safe, not thread-safe in write mode
118
+ - **Gotcha**: Multiple threads writing simultaneously can corrupt state
119
+ - **Why**: Uses asyncio.Lock, not threading.Lock
120
+ - **Solution**: Use single event loop for all write operations
121
+
122
+ ### 3. Hash Function Constraints
123
+ - **Problem**: Hash must be multiple of 8 bits (bytes)
124
+ - **Gotcha**: Custom hash functions with odd bit lengths will fail
125
+ - **Why**: `extract_bits` assumes byte-aligned hash values
126
+ - **Solution**: Ensure hash functions return byte-aligned results
127
+
128
+ ### 4. Bucket Size Tuning
129
+ - **Problem**: max_bucket_size affects performance vs memory trade-offs
130
+ - **Gotcha**: Very small bucket sizes (1) force deep trees, large sizes create big nodes
131
+ - **Why**: Small buckets = more CAS operations, large buckets = bigger serialized nodes
132
+ - **Solution**: Test with your specific workload (default 4 is reasonable)
133
+
134
+ ### 5. Empty Node Pruning
135
+ - **Problem**: Deletions can leave empty nodes in tree
136
+ - **Gotcha**: Empty nodes are automatically pruned except root
137
+ - **Why**: Content addressing means identical empty nodes have same hash
138
+ - **Solution**: Pruning is automatic, but be aware root can become empty
139
+
140
+ ### 6. Serialization Edge Cases
141
+ - **Problem**: InMemoryTreeStore nodes contain non-serializable UUID links
142
+ - **Gotcha**: Attempting to serialize buffer nodes directly will fail
143
+ - **Why**: UUID4.int values exceed DAG-CBOR integer limits
144
+ - **Solution**: Always use `vacate()` or `make_read_only()` before accessing serialized form
145
+
146
+ ### 7. CAS ID Immutability Requirement
147
+ - **Problem**: CAS implementations must return immutable IDs
148
+ - **Gotcha**: Using mutable objects (lists, dicts) as IDs breaks assumptions
149
+ - **Why**: HAMT uses ID equality checks and as dictionary keys
150
+ - **Solution**: Ensure CAS returns immutable types (bytes, CID, int, str, etc.)
151
+
152
+ ### 8. Zarr Metadata Caching
153
+ - **Problem**: ZarrHAMTStore caches `zarr.json` files
154
+ - **Gotcha**: Cache isn't invalidated on writes, can become stale
155
+ - **Why**: Zarr frequently re-reads metadata, caching improves performance
156
+ - **Solution**: Cache is updated on writes, but be aware of this optimization
157
+
158
+ ### 9. Concurrent Operations in Read Mode
159
+ - **Problem**: Read-only mode allows concurrent access
160
+ - **Gotcha**: Switching to write mode while reads are happening is unsafe
161
+ - **Why**: Mode switch changes internal data structures
162
+ - **Solution**: Ensure all operations complete before mode switches
163
+
164
+ ### 10. Key Encoding Assumptions
165
+ - **Problem**: Keys are encoded as UTF-8 bytes for hashing
166
+ - **Gotcha**: Non-UTF-8 string keys or binary keys need special handling
167
+ - **Why**: `key.encode()` assumes UTF-8 encoding
168
+ - **Solution**: Ensure keys are valid UTF-8 strings or modify key handling
169
+
170
+ ## Performance Characteristics
171
+
172
+ ### Time Complexity
173
+ - **Get/Set/Delete**: O(log₂₅₆ n) average case, O(depth) worst case
174
+ - **Iteration**: O(n) for all keys/values
175
+ - **Tree depth**: Typically 1-4 levels for most datasets
176
+
177
+ ### Space Complexity
178
+ - **Node overhead**: ~2KB per node (256 × 8-byte pointers)
179
+ - **Memory efficiency**: Improves with higher bucket sizes
180
+ - **CAS efficiency**: Content addressing deduplicates identical subtrees
181
+
182
+ ### Concurrency
183
+ - **Read-only mode**: Full concurrency support
184
+ - **Write mode**: Single-writer, async-safe
185
+ - **Mode switching**: Blocking operation requiring exclusive access
186
+
187
+ ## Integration Patterns
188
+
189
+ ### 1. IPFS Integration
190
+ ```python
191
+ kubo_cas = KuboCAS()
192
+ hamt = await HAMT.build(cas=kubo_cas)
193
+ await hamt.set("key", "value")
194
+ await hamt.make_read_only()
195
+ cid = hamt.root_node_id # IPFS CID
196
+ ```
197
+
198
+ ### 2. Zarr Storage
199
+ ```python
200
+ hamt = await HAMT.build(cas=kubo_cas, values_are_bytes=True)
201
+ zarr_store = ZarrHAMTStore(hamt, read_only=False)
202
+ dataset.to_zarr(store=zarr_store, zarr_format=3)
203
+ ```
204
+
205
+ ### 3. Encrypted Storage
206
+ ```python
207
+ encryption_key = get_random_bytes(32)
208
+ encrypted_store = SimpleEncryptedZarrHAMTStore(
209
+ hamt, read_only=False, encryption_key=encryption_key, header=b"app-name"
210
+ )
211
+ ```
212
+
213
+ The py-hamt library provides a robust, efficient implementation of HAMTs for content-addressed storage with careful attention to memory management, concurrency, and integration patterns. Understanding these architectural details and gotchas is crucial for successful implementation in production systems.