Skip to content

Commit 271218e

Browse files
authored
Merge pull request #1818 from dvora-h/set-file-and-set-path
JSON set_file and set_path support
2 parents 4831034 + 1757d97 commit 271218e

File tree

2 files changed

+90
-0
lines changed

2 files changed

+90
-0
lines changed

redis/commands/json/commands.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
import os
2+
from json import JSONDecodeError, loads
3+
14
from deprecated import deprecated
25

36
from redis.exceptions import DataError
@@ -213,6 +216,54 @@ def set(self, name, path, obj, nx=False, xx=False, decode_keys=False):
213216
pieces.append("XX")
214217
return self.execute_command("JSON.SET", *pieces)
215218

219+
def set_file(self, name, path, file_name, nx=False, xx=False, decode_keys=False):
220+
"""
221+
Set the JSON value at key ``name`` under the ``path`` to the content
222+
of the json file ``file_name``.
223+
224+
``nx`` if set to True, set ``value`` only if it does not exist.
225+
``xx`` if set to True, set ``value`` only if it exists.
226+
``decode_keys`` If set to True, the keys of ``obj`` will be decoded
227+
with utf-8.
228+
229+
"""
230+
231+
with open(file_name, "r") as fp:
232+
file_content = loads(fp.read())
233+
234+
return self.set(name, path, file_content, nx=nx, xx=xx, decode_keys=decode_keys)
235+
236+
def set_path(self, json_path, root_folder, nx=False, xx=False, decode_keys=False):
237+
"""
238+
Iterate over ``root_folder`` and set each JSON file to a value
239+
under ``json_path`` with the file name as the key.
240+
241+
``nx`` if set to True, set ``value`` only if it does not exist.
242+
``xx`` if set to True, set ``value`` only if it exists.
243+
``decode_keys`` If set to True, the keys of ``obj`` will be decoded
244+
with utf-8.
245+
246+
"""
247+
set_files_result = {}
248+
for root, dirs, files in os.walk(root_folder):
249+
for file in files:
250+
file_path = os.path.join(root, file)
251+
try:
252+
file_name = file_path.rsplit(".")[0]
253+
self.set_file(
254+
file_name,
255+
json_path,
256+
file_path,
257+
nx=nx,
258+
xx=xx,
259+
decode_keys=decode_keys,
260+
)
261+
set_files_result[file_path] = True
262+
except JSONDecodeError:
263+
set_files_result[file_path] = False
264+
265+
return set_files_result
266+
216267
def strlen(self, name, path=None):
217268
"""Return the length of the string JSON value under ``path`` at key
218269
``name``.

tests/test_json.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1392,3 +1392,42 @@ def test_custom_decoder(client):
13921392
assert client.exists("foo") == 0
13931393
assert not isinstance(cj.__encoder__, json.JSONEncoder)
13941394
assert not isinstance(cj.__decoder__, json.JSONDecoder)
1395+
1396+
1397+
@pytest.mark.redismod
1398+
def test_set_file(client):
1399+
import json
1400+
import tempfile
1401+
1402+
obj = {"hello": "world"}
1403+
jsonfile = tempfile.NamedTemporaryFile(suffix=".json")
1404+
with open(jsonfile.name, "w+") as fp:
1405+
fp.write(json.dumps(obj))
1406+
1407+
nojsonfile = tempfile.NamedTemporaryFile()
1408+
nojsonfile.write(b"Hello World")
1409+
1410+
assert client.json().set_file("test", Path.rootPath(), jsonfile.name)
1411+
assert client.json().get("test") == obj
1412+
with pytest.raises(json.JSONDecodeError):
1413+
client.json().set_file("test2", Path.rootPath(), nojsonfile.name)
1414+
1415+
1416+
@pytest.mark.redismod
1417+
def test_set_path(client):
1418+
import json
1419+
import tempfile
1420+
1421+
root = tempfile.mkdtemp()
1422+
sub = tempfile.mkdtemp(dir=root)
1423+
jsonfile = tempfile.mktemp(suffix=".json", dir=sub)
1424+
nojsonfile = tempfile.mktemp(dir=root)
1425+
1426+
with open(jsonfile, "w+") as fp:
1427+
fp.write(json.dumps({"hello": "world"}))
1428+
open(nojsonfile, "a+").write("hello")
1429+
1430+
result = {jsonfile: True, nojsonfile: False}
1431+
print(result)
1432+
assert client.json().set_path(Path.rootPath(), root) == result
1433+
assert client.json().get(jsonfile.rsplit(".")[0]) == {"hello": "world"}

0 commit comments

Comments
 (0)