diff --git a/changes/3ef24cd8510986bf45e39e390b383077.yaml b/changes/3ef24cd8510986bf45e39e390b383077.yaml new file mode 100644 index 00000000000..1392a8ab689 --- /dev/null +++ b/changes/3ef24cd8510986bf45e39e390b383077.yaml @@ -0,0 +1,6 @@ +--- +desc: Added ``indent`` kwarg to ``$lib.json.save()`` to indent serialized json with a number of spaces or a specified string. +prs: +- 4052 +type: feat +... diff --git a/synapse/lib/stormlib/json.py b/synapse/lib/stormlib/json.py index 8cd9a723d2b..6935891abf1 100644 --- a/synapse/lib/stormlib/json.py +++ b/synapse/lib/stormlib/json.py @@ -93,6 +93,7 @@ class JsonLib(s_stormtypes.Lib): 'type': {'type': 'function', '_funcname': '_jsonSave', 'args': ( {'name': 'item', 'type': 'any', 'desc': 'The item to be serialized as a JSON string.', }, + {'name': 'indent', 'type': 'int', 'desc': 'Specify a number of spaces to indent with.', 'default': None}, ), 'returns': {'type': 'str', 'desc': 'The JSON serialized object.', }}}, {'name': 'schema', 'desc': 'Get a JS schema validation object.', @@ -115,10 +116,12 @@ def getObjLocals(self): } @s_stormtypes.stormfunc(readonly=True) - async def _jsonSave(self, item): + async def _jsonSave(self, item, indent=None): + indent = await s_stormtypes.toint(indent, noneok=True) + try: item = await s_stormtypes.toprim(item) - return json.dumps(item) + return json.dumps(item, indent=indent) except Exception as e: mesg = f'Argument is not JSON compatible: {item}' raise s_exc.MustBeJsonSafe(mesg=mesg) diff --git a/synapse/tests/test_lib_stormlib_json.py b/synapse/tests/test_lib_stormlib_json.py index ecdad9568cb..00494dce825 100644 --- a/synapse/tests/test_lib_stormlib_json.py +++ b/synapse/tests/test_lib_stormlib_json.py @@ -12,6 +12,26 @@ async def test_stormlib_json(self): self.eq(((1, 2, 3)), await core.callStorm('return($lib.json.load("[1, 2, 3]"))')) self.eq(('["foo", "bar", "baz"]'), await core.callStorm('return($lib.json.save((foo, bar, baz)))')) + self.eq(('{"foo": 1, "bar": {"baz": "hello"}}'), await core.callStorm('return($lib.json.save(({"foo": 1, "bar": {"baz": "hello"}})))')) + self.eq(('{"foo": 1, "bar": {"baz": "hello"}}'), await core.callStorm('return($lib.json.save(({"foo": 1, "bar": {"baz": "hello"}}), (null)))')) + self.eq(( +'''{ + "foo": 1, + "bar": { + "baz": "hello" + } +}'''), await core.callStorm('return($lib.json.save(({"foo": 1, "bar": {"baz": "hello"}}), indent=(4)))')) + + self.eq(( +'''{ + "foo": 1, + "bar": { + "baz": "hello" + } +}'''), await core.callStorm('return($lib.json.save(({"foo": 1, "bar": {"baz": "hello"}}), indent=2))')) + + with self.raises(s_exc.BadCast): + await core.callStorm('return($lib.json.save(({"foo": 1, "bar": {"baz": "hello"}}), indent=x))') with self.raises(s_exc.BadJsonText): await core.callStorm('return($lib.json.load(foo))')