Package: redis-pydict
redis-pydictA python dictionary that uses Redis as in-memory storage backend to facilitate distributed computing applications development. This library is a small wrapper around Redis that provides dictionary that acts as a drop-in replacement for python dict, but stores data in Redis instead of local program memor, thus key-value pairs written into the python dictionary can be used by other programs that are connected to the same Redis instance / cluster anywhere over the network. The library also provides wrapper around Redis Pub-Sub using which processes can publish and wait for events when new keys are added to the dictionary.InstallationFrom source:git clone git@github.com:Narasimha1997/redis-pydict.git
cd redis-pydict
pip3 install -e .From PIPpip3 install redis-pydictUsageCreating the instance of RedisPyDictfromredis_pydictimportPyRedisDictredis_dict=PyRedisDict(host='localhost',# redis hostport=6379,# redis portdb=0,# redis db (0-15)password=None,# password if using password authnamespace="",# namespace: this is the key prefix, every key inserted into the dict will be prefixed with this namespace string when inserting into Redis, this provides some degree of isolation between namespacescustom=None# use a custom connection, pass a Redis/Redis cluster connection object manually, parameters like `host`, `port`, `db` and `password` will be ignored if this is not None)Supported functions:PyRedisDictis a replacement for dict, and it supports most of the dictionary methods:>>> dir(redis_dict)
['__class__', '__contains__', '__delattr__', '__delitem__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_iter_internal', '_iter_items', '_scan_iter', 'clear', 'enable_publish', 'get', 'items', 'items_matching', 'iter_matching', 'key_namespace', 'keys', 'notification_id', 'redis', 'set_notification_id', 'set_notification_mode', 'subscribe_to_key_events', 'to_dict', 'update', 'values']Publish and subscribe to key set eventsPyRedisDictcan also send key set events when enabled, by default it is not enabled. You can enable it by callingset_notification_mode(true)andset_notification_id(unique_id). Every instance ofPyRedisDictshould be set to a unqiue ID to help diffreniciating with each of them. Here is an exampleOn the sender side:# enable notificationsredis_dict.set_notification_mode(true)# set a unique idredis_dict.set_notification_id('myprocess1')# now this operation will also publish an event which can be captured by subscribersredis_dict['key']="Hello"On receiver side:# this will listen for key set events for key 'key' in the given namespacefor(key,notification_id,value)inredis_dict.subscribe_to_key_events(pattern="key"):print(key,notification_id,value)# optionally you can also use a regex pattern, this example listen for all key events matching pattern key*for(key,notification_id,value)inredis_dict.subscribe_to_key_events(pattern="key*"):print(key,notification_id,value)Examples:Basic set and getdeftest_basic_get_set():d=PyRedisDict(namespace="mykeyspace")d.clear()d['none']=Noned['int']=10d['float']=20.131d['array']=[10,20,30]d['hashmap']={'name':'prasanna','meta':{'age':24,'hobbies':['gaming']}}# assert valuesassertd['int']==10assertd['float']==20.131assertd['array']==[10,20,30]assert(d['hashmap']['name']=='prasanna')and(d['hashmap']['meta']['age']==24)assert(d['none']==None)d.clear()Custom objectsdef test_custom_class_get_set():
   d = PyRedisDict(namespace="mykeyspace")

   d.clear()
   d['obj'] = CustomClass()

   assert d['obj'].add() == (10 + 20 + 30)
   d.clear()Note:PyRedisDictusescPicklefor custom objects.Iterationsdeftest_iterations():d=PyRedisDict(namespace="mykeyspace2")d.clear()d['mykey_none']=Noned['mykey_int']=10d['mykey_float']=20.131d['array']=[10,20,30]d['hashmap']={'name':'prasanna','meta':{'age':24,'hobbies':['gaming']}}# assert valuesassertlen(d)==5assertlen(d.items())==5# find by prefixassertlen(d.items_matching('mykey*'))==3d.clear()Key deletiondeftest_deletion():d=PyRedisDict(namespace="mykeyspace3")d.clear()d['x1']=CustomClass()d['x2']=CustomClass()d['x3']=CustomClass()d['x4']=CustomClass()d['x4']=CustomClass()assert'x1'inddeld['x1']assert'x1'notindd.clear()assertlen(d)==0Converting to/from dictdeftest_conversions():d=PyRedisDict(namespace="mykeyspace")d.clear()d['mykey_none']=Noned['mykey_int']=10d['mykey_float']=20.131d['array']=[10,20,30]d['hashmap']={'name':'prasanna','meta':{'age':24,'hobbies':['gaming']}}assertlen(d.to_dict())==5normal_dict={"mykey_1":10,"mykey_2":20,"mykey_3":"hello","array":[50,60,70]}d.update(normal_dict)assertlen(d)==(5+3)# another key is duplicate (array)assertd['array']==[50,60,70]d.clear()Running testsThis project usespytestfor testing. Instal pytest and runpytestto validate tests, make sure you set-up Redis locally to test the process.ContributionsFeel free to try this library, suggest changes, raise issues, send PRs.