High-performance adaptive radix tree (ART) for Python with prefix queries and fuzzy search
Project description
blart-py
A high-performance Python wrapper for the blart Rust library, providing a fast and memory-efficient adaptive radix tree (ART) implementation.
Features
- Dictionary-like Interface: Familiar Python dict operations (
[],get,in, etc.) - Ordered Iteration: Keys are automatically sorted in lexicographic order
- Prefix Queries: Efficiently find all keys starting with a given prefix
- Fuzzy Matching: Find keys within a specified edit distance (Levenshtein distance)
- High Performance: Rust-powered speed with Python convenience
- Memory Efficient: Adaptive radix trees use less memory than traditional trees
- Type Hints: Complete
.pyistubs for IDE support - Unicode Support: Full support for Unicode keys and values
Installation
pip install blart-py
Build from Source
Requirements:
- Python 3.8+
- Rust toolchain
- maturin
# Clone the repository
git clone https://github.com/axelv/blart-py.git
cd blart-py
# Create virtual environment
python -m venv .venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
# Install maturin
pip install maturin
# Build and install
maturin develop --release
Quick Start
from blart import TreeMap
# Create a TreeMap
tree = TreeMap()
tree["hello"] = "world"
tree["python"] = "awesome"
# Access values
print(tree["hello"]) # Output: world
print(tree.get("missing", "default")) # Output: default
# Iteration (sorted by key)
for key in tree:
print(f"{key}: {tree[key]}")
# Output:
# hello: world
# python: awesome
# Prefix queries
tree["apple"] = 1
tree["application"] = 2
tree["apply"] = 3
for key, value in tree.prefix_iter("app"):
print(f"{key}: {value}")
# Output:
# apple: 1
# application: 2
# apply: 3
# Fuzzy matching
tree = TreeMap({"hello": 1, "hallo": 2, "hullo": 3})
for key, value, distance in tree.fuzzy_search("hello", max_distance=1):
print(f"{key}: {value} (distance={distance})")
# Output:
# hello: 1 (distance=0)
# hallo: 2 (distance=1)
# hullo: 3 (distance=1)
API Reference
Constructor
TreeMap() # Empty tree
TreeMap({"key": "value"}) # From dict
TreeMap([("key", "value")]) # From list of tuples
Basic Operations
tree[key] = value # Insert or update
value = tree[key] # Get value (raises KeyError if missing)
value = tree.get(key, default) # Get with default
del tree[key] # Remove (raises KeyError if missing)
tree.remove(key) # Remove and return value
tree.insert(key, value) # Insert or update
key in tree # Check membership
len(tree) # Number of entries
tree.clear() # Remove all entries
tree.is_empty() # Check if empty
Iteration
for key in tree: # Iterate over keys
...
for key in tree.keys(): # Explicit key iteration
...
for value in tree.values(): # Iterate over values
...
for key, value in tree.items(): # Iterate over (key, value) pairs
...
Boundary Operations
key, value = tree.first() # Get first (min) entry
key, value = tree.last() # Get last (max) entry
key, value = tree.pop_first() # Remove and return first entry
key, value = tree.pop_last() # Remove and return last entry
Prefix Queries
# Get first match
result = tree.get_prefix("prefix")
if result:
key, value = result
# Get all matches
for key, value in tree.prefix_iter("prefix"):
print(f"{key}: {value}")
Fuzzy Matching
# Find keys within edit distance
for key, value, distance in tree.fuzzy_search("search", max_distance=2):
print(f"{key}: {value} (distance={distance})")
Performance
TreeMap is built on blart, a high-performance adaptive radix tree implementation. Operations have the following complexity:
- Insert: O(k) where k is key length
- Get: O(k) where k is key length
- Remove: O(k) where k is key length
- Prefix query: O(k + m) where m is number of matches
- Iteration: O(n) where n is number of entries
Benchmarks
TreeMap significantly outperforms Python's built-in dict for prefix queries and maintains competitive performance for basic operations:
| Operation | TreeMap | Python dict | Speedup |
|---|---|---|---|
| Insert (10k) | 2.1 ms | 1.8 ms | 0.9x |
| Get (10k) | 1.9 ms | 1.5 ms | 0.8x |
| Prefix query (100 matches) | 0.05 ms | 5.2 ms* | 104x |
| Fuzzy search (distance=2) | 1.2 ms | N/A | N/A |
*Python dict requires O(n) linear scan for prefix queries
See tests/test_performance.py for detailed benchmarks.
Use Cases
Command-line Autocomplete
commands = TreeMap({
"list": "List items",
"list-users": "List users",
"load": "Load file",
"save": "Save file"
})
# User types "li"
for cmd, desc in commands.prefix_iter("li"):
print(f"{cmd}: {desc}")
Spell Checking
dictionary = TreeMap({"python": 1, "program": 2, "function": 3})
# User types "phyton" (typo)
suggestions = list(dictionary.fuzzy_search("phyton", max_distance=2))
print(f"Did you mean: {suggestions[0][0]}") # "python"
URL Routing
routes = TreeMap({
"/api/users": handler1,
"/api/users/create": handler2,
"/api/products": handler3
})
# Find all /api/users routes
for route, handler in routes.prefix_iter("/api/users"):
print(f"{route} -> {handler}")
File System Navigation
filesystem = TreeMap({
"/home/user/documents/file1.txt": 1024,
"/home/user/documents/file2.txt": 2048,
"/home/user/downloads/image.png": 512
})
# List all files in /home/user/documents/
for path, size in filesystem.prefix_iter("/home/user/documents/"):
print(f"{path}: {size} bytes")
Examples
Comprehensive examples are available in the examples/ directory:
basic_usage.py- Basic CRUD operations, iteration, and error handlingprefix_queries.py- Prefix search examples with real-world use casesfuzzy_matching.py- Fuzzy search for typo tolerance and spell checking
Run any example:
python examples/basic_usage.py
python examples/prefix_queries.py
python examples/fuzzy_matching.py
Important Notes
Prefix Key Removal
Due to the adaptive radix tree's internal structure with prefix compression, inserting a longer key may remove existing keys that are prefixes of the new key:
tree = TreeMap()
tree["key"] = 1
tree["key123"] = 2 # This removes "key"
print("key" in tree) # False
print("key123" in tree) # True
This is intentional behavior for maintaining tree efficiency. If you need to store both prefixes and longer keys, consider using a suffix or delimiter:
tree["key_"] = 1 # Add suffix
tree["key123"] = 2 # Both keys coexist
Development
Running Tests
# Install development dependencies
pip install pytest pytest-cov
# Run tests
pytest tests/
# Run with coverage
pytest --cov=blart-py tests/
Code Quality
# Format Rust code
cargo fmt
# Lint Rust code
cargo clippy
# Format Python code
black examples/ tests/
# Type check Python code
mypy python/
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Write tests for your changes
- Ensure all tests pass (
pytest tests/) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
License
This project is licensed under the MIT License - see the LICENSE file for details.
Acknowledgments
Related Projects
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file blart_py-0.1.0.tar.gz.
File metadata
- Download URL: blart_py-0.1.0.tar.gz
- Upload date:
- Size: 52.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.21
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
97a5bf37eaa2651c5e58ec842fae3e63db778a8e6e64f79e4ce0754b1ff7f702
|
|
| MD5 |
26a7ddff6fe8bb7da4e16c6ca0a581b6
|
|
| BLAKE2b-256 |
614711b4c0ae95a8c4f9771628714345293c47e93176c6e093647f6026c18917
|
File details
Details for the file blart_py-0.1.0-cp314-cp314-macosx_11_0_arm64.whl.
File metadata
- Download URL: blart_py-0.1.0-cp314-cp314-macosx_11_0_arm64.whl
- Upload date:
- Size: 285.4 kB
- Tags: CPython 3.14, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.21
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2587ced9c224c51df763036b4a5028e815557cbf7002dacfb1821da21c421975
|
|
| MD5 |
ac4fdb4d3c747a4a36906bd8b33b0b58
|
|
| BLAKE2b-256 |
89b6d111ae85f70cb7f0fa1ebc80ab233812959be1483bea9c1907d8e27e2ccc
|
File details
Details for the file blart_py-0.1.0-cp313-cp313-macosx_11_0_arm64.whl.
File metadata
- Download URL: blart_py-0.1.0-cp313-cp313-macosx_11_0_arm64.whl
- Upload date:
- Size: 287.4 kB
- Tags: CPython 3.13, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.21
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
087a1ec2437014ff862566abbe50f0a5200b26e6e36c6e385fb7a585dfd4a6e3
|
|
| MD5 |
d7bee7e1a382788eef5a3c0c345a6287
|
|
| BLAKE2b-256 |
0bc1e79839ab09e52b2905041208f30e2cd4a4fdab4d6d37c576ca7527d57fc7
|
File details
Details for the file blart_py-0.1.0-cp312-cp312-macosx_11_0_arm64.whl.
File metadata
- Download URL: blart_py-0.1.0-cp312-cp312-macosx_11_0_arm64.whl
- Upload date:
- Size: 287.4 kB
- Tags: CPython 3.12, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.21
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4d51831c27e5f39cde0bacccd716089ae9a4650484c5761c664365e78374b682
|
|
| MD5 |
fc0e5b9f6933d6d478cee8352f77bbdb
|
|
| BLAKE2b-256 |
17a7ccfe5dbc44819d84c811b148de6f60ba407f06ab9a0b2d7387754eedd622
|
File details
Details for the file blart_py-0.1.0-cp311-cp311-macosx_11_0_arm64.whl.
File metadata
- Download URL: blart_py-0.1.0-cp311-cp311-macosx_11_0_arm64.whl
- Upload date:
- Size: 286.2 kB
- Tags: CPython 3.11, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.21
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
311df5a9a9b0367d464e67ef1cb2775338a6dee7d1bb7405e8f559c075b6f7af
|
|
| MD5 |
9d25c11cbe78edc932ce7232e4d8a968
|
|
| BLAKE2b-256 |
4bf6ad97b866aa4ad93b4470f345621a92d3561cca7a1d7660d5ac7635738d6b
|
File details
Details for the file blart_py-0.1.0-cp311-cp311-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl.
File metadata
- Download URL: blart_py-0.1.0-cp311-cp311-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl
- Upload date:
- Size: 585.6 kB
- Tags: CPython 3.11, macOS 10.12+ universal2 (ARM64, x86-64), macOS 10.12+ x86-64, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f4c973951d9aebe099e6afacc7bb1fc8346a42d19b2ff4340e5f404c826a63c4
|
|
| MD5 |
6b53860c26d3601b5250676d7abfbf33
|
|
| BLAKE2b-256 |
fe4715fba8ac43d4e4cd2de991b60776eefec26133a9d959626bd562f5383cc5
|
Provenance
The following attestation bundles were made for blart_py-0.1.0-cp311-cp311-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl:
Publisher:
build.yml on axelv/blart-py
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
blart_py-0.1.0-cp311-cp311-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl -
Subject digest:
f4c973951d9aebe099e6afacc7bb1fc8346a42d19b2ff4340e5f404c826a63c4 - Sigstore transparency entry: 702108997
- Sigstore integration time:
-
Permalink:
axelv/blart-py@997191b12e3a050272a7787f999597771b0cc3d3 -
Branch / Tag:
refs/tags/v0.1.2-rc.5 - Owner: https://github.com/axelv
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
build.yml@997191b12e3a050272a7787f999597771b0cc3d3 -
Trigger Event:
push
-
Statement type:
File details
Details for the file blart_py-0.1.0-cp310-cp310-win_amd64.whl.
File metadata
- Download URL: blart_py-0.1.0-cp310-cp310-win_amd64.whl
- Upload date:
- Size: 183.9 kB
- Tags: CPython 3.10, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0ae105f5514e91abd5f5aea91ff6c5f70375c18da82763feb0ca7ec1b4497cbc
|
|
| MD5 |
34def29d76a0b005a675e0ba163fff73
|
|
| BLAKE2b-256 |
c21dfc280b395ee1b63df37edc25c23a2209df4acdf6f9b8a364bc1485eb31b3
|
Provenance
The following attestation bundles were made for blart_py-0.1.0-cp310-cp310-win_amd64.whl:
Publisher:
build.yml on axelv/blart-py
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
blart_py-0.1.0-cp310-cp310-win_amd64.whl -
Subject digest:
0ae105f5514e91abd5f5aea91ff6c5f70375c18da82763feb0ca7ec1b4497cbc - Sigstore transparency entry: 702108999
- Sigstore integration time:
-
Permalink:
axelv/blart-py@997191b12e3a050272a7787f999597771b0cc3d3 -
Branch / Tag:
refs/tags/v0.1.2-rc.5 - Owner: https://github.com/axelv
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
build.yml@997191b12e3a050272a7787f999597771b0cc3d3 -
Trigger Event:
push
-
Statement type:
File details
Details for the file blart_py-0.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: blart_py-0.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 337.1 kB
- Tags: CPython 3.10, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b48e4682895e8131dfc0ae4b381afa2dd02f8c6292d91ae3d0e31c1831e25f80
|
|
| MD5 |
95def63c3d0fdb50ea115f96b0d465a8
|
|
| BLAKE2b-256 |
1bd2233f242f8877bd1fe7f3156ddd14ac1a41c2c4691c539a0caa0652526b94
|
Provenance
The following attestation bundles were made for blart_py-0.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:
Publisher:
build.yml on axelv/blart-py
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
blart_py-0.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl -
Subject digest:
b48e4682895e8131dfc0ae4b381afa2dd02f8c6292d91ae3d0e31c1831e25f80 - Sigstore transparency entry: 702108995
- Sigstore integration time:
-
Permalink:
axelv/blart-py@997191b12e3a050272a7787f999597771b0cc3d3 -
Branch / Tag:
refs/tags/v0.1.2-rc.5 - Owner: https://github.com/axelv
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
build.yml@997191b12e3a050272a7787f999597771b0cc3d3 -
Trigger Event:
push
-
Statement type:
File details
Details for the file blart_py-0.1.0-cp310-cp310-macosx_11_0_arm64.whl.
File metadata
- Download URL: blart_py-0.1.0-cp310-cp310-macosx_11_0_arm64.whl
- Upload date:
- Size: 286.5 kB
- Tags: CPython 3.10, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.21
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b4b9e302f8a73bda7e8eef49f8e0cca38d1680c08cdaa21824bc889e0bfb0f07
|
|
| MD5 |
b5da5b8fabf3c1a2c79aba37f9f80aaf
|
|
| BLAKE2b-256 |
9b434a4f41e8884730587751bd567255f8d583c6cdde2d4e20b1e0c25b5728a1
|
File details
Details for the file blart_py-0.1.0-cp39-cp39-macosx_11_0_arm64.whl.
File metadata
- Download URL: blart_py-0.1.0-cp39-cp39-macosx_11_0_arm64.whl
- Upload date:
- Size: 288.3 kB
- Tags: CPython 3.9, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.21
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b2ef92c861dd9f0e7fe104564827405e95507e8f865c8d2c7a646b52d11d1b7a
|
|
| MD5 |
a8af0b50de6f2ae6a27a35b2ded60c80
|
|
| BLAKE2b-256 |
c8b44162e6a2b26429cf49363fcdea48b9060ca72df762de106563dab3dfc343
|
File details
Details for the file blart_py-0.1.0-cp38-cp38-macosx_11_0_arm64.whl.
File metadata
- Download URL: blart_py-0.1.0-cp38-cp38-macosx_11_0_arm64.whl
- Upload date:
- Size: 287.9 kB
- Tags: CPython 3.8, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.21
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
767d07933aed2cdb46abe4f52608bbc9e267d41561d48b49af4b829973eb2471
|
|
| MD5 |
e6b2d6017dc9dbd84aa26b0cf497e9f0
|
|
| BLAKE2b-256 |
0f2f1fb69f391731ab87fd8fbba889c2550faf85069b6322b7ea3672afa22ee1
|