A context-aware in-memory dictionary with Redis support, TTLs, and versioning.
Project description
ContextDict — The Smartest Drop-in Dict for Python
pip install contextdict
Overview
ContextDict is a powerful in-memory dictionary enhanced with:
- Redis support (optional backend)
- TTL (Time-to-Live) per key
- Versioning with timestamped history
- Thread-safe operations
- Async-ready via
asyncio.to_thread
Features
- Supports complex keys (tuples, dicts, lists)
- Remembers all versions per key
- TTL-based auto-expiry
- Thread-safe with
threading.Lock - Async API:
aset,aget,afilter - Optional Redis backend for persistence and scaling
- Filter with custom logic
- Drop-in usage:
dict[key] = value
Installation
pip install contextdict
Quick Example
from contextdict import ContextDict
hd = ContextDict()
hd.set(('user', 1), {'name': 'Alice'}, ttl=60)
print(hd.get(('user', 1)))
# Later...
print(hd.versions(('user', 1)))
Redis-Enabled:
hd = ContextDict(use_redis=True, redis_config={"host": "localhost", "port": 6379})
hd.set("token", "abc123", ttl=10)
print(hd.get("token"))
Why filter() Matters
Modern applications often store fast-changing or contextual data in memory — such as:
- Active user sessions
- In-progress background jobs
- Temporary tokens or flags
- Ephemeral configuration changes
When querying this type of in-memory data, you often need to:
- Filter for a specific condition (e.g., active users, jobs with errors)
- Skip expired or invalid keys (TTL aware)
- Perform quick in-memory lookups like a smart cache
ContextDict provides a built-in filter() method to handle this elegantly:
Example:
hd.set("user:1", {"status": "active"})
hd.set("user:2", {"status": "inactive"})
active_users = hd.filter(lambda k, v: v["status"] == "active")
print(active_users) # {'user:1': {'status': 'active'}}
More Real-World Examples
1. Filter keys with values greater than a threshold
hd.set("a", 10)
hd.set("b", 50)
hd.set("c", 5)
high_values = hd.filter(lambda k, v: v > 10)
# Result: {'b': 50}
2. Filter only tuple-based keys
hd.set(("user", 1), {"age": 30})
hd.set("admin", {"age": 50})
only_tuples = hd.filter(lambda k, v: isinstance(k, tuple))
# Result: {('user', 1): {'age': 30}}
3. Filter expired-safe tokens
hd.set("t1", "token1", ttl=1)
hd.set("t2", "token2", ttl=10)
# After a delay, only non-expired tokens will be returned
valid_tokens = hd.filter(lambda k, v: True)
4. Filter with key prefix
hd.set("config:theme", "dark")
hd.set("config:lang", "en")
hd.set("session:token", "abc")
configs = hd.filter(lambda k, v: str(k).startswith("config:"))
# Result: {'config:theme': 'dark', 'config:lang': 'en'}
5. Filter values of a specific type
hd.set("x", [1, 2, 3])
hd.set("y", "hello")
hd.set("z", {"nested": True})
lists_only = hd.filter(lambda k, v: isinstance(v, list))
# Result: {'x': [1, 2, 3]}
Benefits:
- Skips expired entries automatically (TTL-safe)
- Works with complex keys like tuples or lists
- Returns only the subset you care about
- Makes ContextDict a functional alternative to Redis/SQLite for in-memory filtering
- Enables expressive, one-liner queries for cached or ephemeral data
This enables use cases like:
- Fetching only recent successful tasks
- Getting all configuration keys with a specific prefix
- Querying memory like a lightweight database
Modern applications often store fast-changing or contextual data in memory — such as:
- Active user sessions
- In-progress background jobs
- Temporary tokens or flags
- Ephemeral configuration changes
When querying this type of in-memory data, you often need to:
- Filter for a specific condition (e.g., active users, jobs with errors)
- Skip expired or invalid keys (TTL aware)
- Perform quick in-memory lookups like a smart cache
ContextDict provides a built-in filter() method to handle this elegantly:
Example:
hd.set("user:1", {"status": "active"})
hd.set("user:2", {"status": "inactive"})
active_users = hd.filter(lambda k, v: v["status"] == "active")
print(active_users) # {'user:1': {'status': 'active'}}
Benefits:
- Skips expired entries automatically (TTL-safe)
- Works with complex keys like tuples or lists
- Returns only the subset you care about
- Makes ContextDict a functional alternative to Redis/SQLite for in-memory filtering
This enables use cases like:
- Fetching only recent successful tasks
- Getting all configuration keys with a specific prefix
- Querying memory like a lightweight database
Async Usage
import asyncio
async def run():
await hd.aset("k1", "v1", ttl=5)
value = await hd.aget("k1")
print(value)
asyncio.run(run())
Coming Soon
- Eviction policy (LRU)
- Namespacing
- Cache stats & metrics
- Schema-aware validation
License
MIT — use it, improve it, share it.
©️ 2025 Yerram Mahendra Reddy
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 Distributions
Built Distribution
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 contextdict-0.1.0-py3-none-any.whl.
File metadata
- Download URL: contextdict-0.1.0-py3-none-any.whl
- Upload date:
- Size: 7.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.9.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9641cbba4efae075c5b0fc2712d911d6427c65b70ed85af7cefbe049192b45a6
|
|
| MD5 |
de4bf98b73137d79b21bf0f643700159
|
|
| BLAKE2b-256 |
79aa9760bbdb9d8c52c09ae1fbd1ffe99bc66d7570dc19b5b943abbdaef31196
|