A thin convenience wrapper around redis-py for storing Python values (via pickle), working with Redis hashes, performing atomic updates, and managing distributed locking primitives.
pip install dkredis
from dkredis import dkredis
r = dkredis.connect()connect() reads REDIS_HOST and REDIS_PASSWORD from environment
variables, defaulting to localhost:6379.
Any pickleable value can be stored and retrieved:
from dkredis.dkredis import set_pyval, get_pyval, pop_pyval
set_pyval('mykey', {'answer': 42}, secs=300) # expires in 5 minutes
get_pyval('mykey') # {'answer': 42}
pop_pyval('mykey') # {'answer': 42}, then deletes the keyStore and retrieve dicts as Redis hashes (string values only):
from dkredis.dkredis import set_dict, get_dict
set_dict('user:1', {'name': 'Alice', 'role': 'admin'}, secs=600)
get_dict('user:1') # {'name': 'Alice', 'role': 'admin'}update() uses WATCH/MULTI pipelines for optimistic locking:
from dkredis.dkredis import update, setmax, setmin
r.set('counter', 40)
update('counter', lambda val: val + 2) # atomically set to 42
setmax('highscore', b'100') # r[key] := max(r[key], val)
setmin('lowscore', b'5') # r[key] := min(r[key], val)remove_if() atomically deletes a key only if it holds an expected value
(implemented via a Lua script):
from dkredis.dkredis import remove_if
remove_if('mykey', expected_value)fetch_lock -- prevents thundering-herd on cache misses. Only one process
fetches fresh data; others receive False and should fall back to stale
cache:
from dkredis.dkredislocks import fetch_lock
with fetch_lock('weatherapi', timeout=10) as should_fetch:
if should_fetch:
data = call_external_api()
cache.set('weather', data, 60)
else:
time.sleep(1)
data = cache.get('weather')rate_limiting_lock -- sets multiple keys atomically with MSETNX to
enforce a per-resource cooldown period:
from dkredis.dkredislocks import rate_limiting_lock
if rate_limiting_lock(['smtp.example.com'], seconds=15):
send_email()mutex -- a polling mutex using SETNX with expiry-based recovery:
from dkredis.dkredislocks import mutex
with mutex('mylock', seconds=30, timeout=60):
# mutual exclusion zone
...mhkeyget() fetches one field from all hashes matching a key pattern:
from dkredis.dkredis import mhkeyget
mhkeyget('lock.*', 'x')
# {'lock.a': '1', 'lock.b': '2', 'lock.c': '3'}- Python 3
redis==5.0.1- A running Redis server (
localhost:6379by default)