An extension to redis-py for using Redis' ReJSON module

RedisJSON, updated 🕥 2023-02-08 08:30:24

license pypi PyVersions GitHub issues Codecov Known Vulnerabilities

RedisJSON Python Client

Forum Discord

Deprecation notice

As of redis-py 4.0.0 this library is deprecated. It's features have been merged into redis-py. Please either install it from pypy or the repo.


rejson-py is a package that allows storing, updating and querying objects as JSON documents in a Redis database that is extended with the ReJSON module. The package extends redis-py's interface with ReJSON's API, and performs on-the-fly serialization/deserialization of objects to/from JSON.

Installation

bash $ pip install rejson

Development

  1. Create a virtualenv to manage your python dependencies, and ensure it's active. virtualenv -v venv
  2. Install pypoetry to manage your dependencies. pip install --user poetry
  3. Install dependencies. poetry install

tox runs all tests as its default target. Running tox by itself will run unit tests. Ensure you have a running redis, with the module loaded.

Usage example

```python from rejson import Client, Path

rj = Client(host='localhost', port=6379, decode_responses=True)

# Set the key obj to some object obj = { 'answer': 42, 'arr': [None, True, 3.14], 'truth': { 'coord': 'out there' } } rj.jsonset('obj', Path.rootPath(), obj)

# Get something print 'Is there anybody... {}?'.format( rj.jsonget('obj', Path('.truth.coord')) )

# Delete something (or perhaps nothing), append something and pop it rj.jsondel('obj', Path('.arr[0]')) rj.jsonarrappend('obj', Path('.arr'), 'something') print '{} popped!'.format(rj.jsonarrpop('obj', Path('.arr')))

# Update something else rj.jsonset('obj', Path('.answer'), 2.17)

# And use just like the regular redis-py client jp = rj.pipeline() jp.set('foo', 'bar') jp.jsonset('baz', Path.rootPath(), 'qaz') jp.execute()

# If you use non-ascii character in your JSON data, you can add the no_escape flag to JSON.GET command obj_non_ascii = { 'non_ascii_string': 'hyvää' } rj.jsonset('non-ascii', Path.rootPath(), obj_non_ascii) print '{} is a non-ascii string'.format(rj.jsonget('non-ascii', Path('.non_ascii_string'), no_escape=True)) ```

Encoding/Decoding

rejson-py uses Python's json. The client can be set to use custom encoders/decoders at creation, or by calling explicitly the setEncoder() and setDecoder() methods, respectively.

The following shows how to use this for a custom class that's stored as a JSON string for example:

```python

from json import JSONEncoder, JSONDecoder from rejson import Client

class CustomClass(object): "Some non-JSON-serializable" def init(self, s=None): if s is not None: # deserialize the instance from the serialization if s.startswith('CustomClass:'): ... else: raise Exception('unknown format') else: # initialize the instance ...

   def __str__(self):
       _str = 'CustomClass:'
       # append the instance's state to the serialization
       ...
       return _str

   ...

class CustomEncoder(JSONEncoder): "A custom encoder for the custom class" def default(self, obj): if isinstance(obj, CustomClass): return str(obj) return json.JSONEncoder.encode(self, obj)

class TestDecoder(JSONDecoder): "A custom decoder for the custom class" def decode(self, obj): d = json.JSONDecoder.decode(self, obj) if isinstance(d, basestring) and d.startswith('CustomClass:'): return CustomClass(d) return d

# Create a new instance of CustomClass obj = CustomClass()

# Create a new client with the custom encoder and decoder rj = Client(encoder=CustomEncoder(), decoder=CustomDecoder())

# Store the object rj.jsonset('custom', Path.rootPath(), obj))

# Retrieve it obj = rj.jsonget('custom', Path.rootPath()) ```

API

As rejson-py exposes the same methods as redis-py, it can be used as a drop-in replacement. On top of Redis' core commands, the client also adds ReJSON's vocabulary and a couple of helper methods. These are documented in the API.md file, which can be generated by running:

bash $ python gendoc rejson > API.md

For complete documentation about ReJSON's commands, refer to ReJSON's website.

License

BSD 2-Clause

Issues

Add deprecation warning and update version

opened on 2022-04-11 12:13:55 by dvora-h None

How do I set expiry?

opened on 2021-12-18 13:36:54 by bansalnaman15

``` obj = { "id": 1, "uname": "abc" }

rj.jsonset('key1', Path.rootPath(), obj) ```

fix typo in README.md

opened on 2021-11-05 06:16:50 by blakechi
  • change typo in line:125 from TestDecoder to CustomDecoder

redis.exceptions.ResponseError: unknown command 'JSON.SET'

opened on 2021-10-21 19:34:15 by lRafaelOliveira

Ola, Estou tentando Utilizar o REJSON no python, ja iniciei utilizando o pip install rejson, instala normal, porem sempre me retorna esse erro, que nao esta encontrando o comando JSON.SET.. o que poderia ser ? estou rodando o servidor redis no localhost do windows..

File "d:\RAFA\WHATSAPP\whatsapp-bot\redis2.py", line 7, in <module> r.execute_command('JSON.SET',"dic") File "C:\Users\hto-r\AppData\Local\Programs\Python\Python39\lib\site-packages\redis\client.py", line 901, in execute_command return self.parse_response(conn, command_name, **options) File "C:\Users\hto-r\AppData\Local\Programs\Python\Python39\lib\site-packages\redis\client.py", line 915, in parse_response response = connection.read_response() File "C:\Users\hto-r\AppData\Local\Programs\Python\Python39\lib\site-packages\redis\connection.py", line 756, in read_response raise response redis.exceptions.ResponseError: unknown command 'JSON.SET'

Bulk load / batch upsert support

opened on 2021-04-26 17:47:27 by avico78

Is rejon support batch upsert or bulk load?

for reference: https://docs.couchbase.com/python-sdk/2.5/batching-operations.html#asynchronous-batching

How to search in a list?

opened on 2021-04-24 21:08:26 by avico78

I see a key pointing to list of json :
python redis_json_client.jsonset('customers', Path.rootPath(), { "customers": []}) ```` example of insreted json customer_json: { "customer_status": "Active", "first_name": "Leonard", "last_name": "Cohen", "customer_no": 1 } So now I append each of the json as following: redis_json_client.jsonarrappend('customers', Path('.customers'), customer_json) ```

I'd like to preform a search finding specific customer_no I tried something like: customer_redis = redis_json_client.jsonget('customers', Path('customer_no'),370471789) Q: 1.The reaosn for creating a list of json is that i'd like to some category collection in redis ,i wonder how bad it effect the performance , I could also assign the json as : key,customer_json instead of key,[customer_json]

2.How could i preform a search for specific json where key holds a list of json as desribe above?

Releases

Version 0.5.6 2021-11-18 10:04:18

Changes

  • Fixing packaging issue causing install failures (#70)

Version 0.5.5 2021-11-17 10:47:47

Changes

  • pinning redis to 3.5.3 and updating minor version (#68)
  • Adding deprecation notice (#66)
  • Python 3.10 support and trove (#63)
  • JSON.TOGGLE and JSON.CLEAR (#55)
  • fixes issues #44 #45 setDecoder not working, TypeError when reJSON returns None (#46)
  • remove unused MODULE_INFO (#36)

0.5.3 fix requirements list 2020-01-05 14:56:08

0.5.2 Fix FreeBSD + Python 3.6.1 2019-12-15 13:50:26

  • 28 #30 Use io.open() and 'utf-8' to read description

0.5.1 Fix Mac OS support 2019-12-01 18:34:07

  • Use io.open() and 'utf-8' encoding to read version

0.5.0 no_escape flag 2019-09-01 15:24:24

  • 26 Fixing retrieving non-ascii string with JSON.GET, added no_escape flag

RedisJSON

A Redis module that implements JSON as a native data type.

GitHub Repository Homepage

redis python json rejson