Skip to content

Commit b992a43

Browse files
committed
Introducing generic as_tuples function which can be used to parse JSON directly.
1 parent a621da1 commit b992a43

File tree

1 file changed

+34
-0
lines changed

1 file changed

+34
-0
lines changed

c8y_api/model/_parser.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,42 @@
55
from typing import Set
66

77
from c8y_api.model._base import ComplexObject
8+
from c8y_api.model._util import _StringUtil
89

910

11+
def as_tuples(json_data, *path: str | tuple):
12+
"""Parse a JSON structure as tuples from paths.
13+
14+
Args:
15+
json_data (dict): A JSON structure as Python dict
16+
path (*str|tuple): Path(s) to extract from
17+
the structure; Use dots to separate JSON levels; Arrays are not
18+
supported.
19+
20+
Mote: This function automatically converts path segments from
21+
Python snake_case to pascalCase, e.g. `creation_time` will match
22+
both `creation_time` and `creationTime` fields.
23+
24+
Returns:
25+
A tuple with `len(path)` elements containing the values as-is defined
26+
in the JSON structure; an invalid path will result in None.
27+
"""
28+
def resolve(segments, default=None):
29+
json_level = json_data
30+
for segment in segments[:-1]:
31+
if segment in json_level:
32+
json_level = json_level[segment]
33+
continue
34+
pascal_segment = _StringUtil.to_pascal_case(segment)
35+
if pascal_segment in json_level:
36+
json_level = json_level[pascal_segment]
37+
continue
38+
return default
39+
return json_level.get(segments[-1], json_level.get(_StringUtil.to_pascal_case(segments[-1]), default))
40+
41+
# each p in path(s) can be a string or a tuple
42+
return tuple(resolve(p[0].split('.'), p[1]) if isinstance(p, tuple) else resolve(p.split('.')) for p in path )
43+
1044
class SimpleObjectParser(object):
1145
"""A parser for simple (without fragments) Cumulocity database objects.
1246

0 commit comments

Comments
 (0)