Skip to content

response_parser_json

ResponseParserJSON

Description

Json is the response for most of the REST API requests give. This class provides few methods which parse and get the required details.

Source code in libs\cafex_api\src\cafex_api\response_parser_json.py
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
class ResponseParserJSON:
    """
    Description:
        Json is the response for most of the REST API requests give.
        This class provides few methods which parse and get the required details.

    """

    def __init__(self):
        self.logger = CoreLogger(name=__name__).get_logger()

    def get_key_value(self, **kwargs) -> Any:
        """Extracts the value(s) of thr key from the JSON data, optionally
        searching nested structures.

        Kwargs:
            json: The JSON data (string or dictionary).
            key: The key to retrieve the value for.
            nested: Whether to search for the key in nested structures (default: False).

        Returns:
            The value associated with the key
            The list of values if nested is True and multiple keys are found.

        Raises:
            ValueError: If required arguments are missing or invalid.
            json.JSONDecodeError: If the JSON data is invalid.

        Examples:
            # gets the first key Item. no nested search
            response_parser.get_key_value(json=dict_response, key=item)
            # searches nested keys and gets all the lists
            self.response_parser.get_key_value(json=dict_response, key=item, nested=True)
        """
        try:
            if "json" not in kwargs:
                self.logger.info("No 'json' parameter Passed")
                raise ValueError("'json' parameter is required.")
            if "key" not in kwargs:
                self.logger.info("No 'key' parameter Passed")
                raise ValueError("'key' parameter is required.")

            json_data = kwargs.get("json")
            key = kwargs.get("key")
            nested = kwargs.get("nested", False)

            if not json_data:
                raise ValueError("The 'json_data' parameter cannot be null or empty.")
            if not key:
                raise ValueError("The 'key' parameter cannot be null or empty.")
            if not isinstance(nested, bool):
                raise ValueError("The 'nested' parameter must be a boolean")

            obj_parse_data = ParseJsonData()
            return obj_parse_data.get_value_of_key(json_data, key, nested)
        except Exception as e:
            self.logger.exception("Error in extracting the value(s) of the specified key: %s", e)
            raise e

    def compare_json(
        self,
        expected_json: str | dict,
        actual_json: str | dict,
        ignore_keys: list[str] | None = None,
        ignore_extra: bool = False,
    ) -> bool | tuple[bool, list[str]]:
        """Compares two JSON structures (strings or dictionaries).

        Args:
            expected_json: The expected JSON data (string or dictionary).
            actual_json: The actual JSON data (string or dictionary).
            ignore_keys: A list of keys to ignore during comparison (default: None).
            ignore_extra: Whether to ignore extra keys in actual_json (default: False).

        Returns:
            True if the JSON structures are equal (considering ignore_keys and ignore_extra),
            otherwise a tuple containing False and a list of mismatches.

        Raises:
            ValueError: If the input JSON data is invalid.

        Examples:
            # Comparing two JSON strings
            result = compare_json('{"a": 1, "b": 2}', '{"a": 1, "b": 2}')
            assert result is True

            # Comparing two dictionaries
            result = compare_json({"a": 1, "b": 2}, {"a": 1, "b": 2})
            assert result is True

            # Ignoring specific keys
            result = compare_json('{"a": 1, "b": 2}', '{"a": 1, "b": 3}', ignore_keys=["b"])
            assert result is True

            # Ignoring extra keys
            result = compare_json('{"a": 1}', '{"a": 1, "b": 2}', ignore_extra=True)
            assert result is True

            # Mismatch example
            result = compare_json('{"c": 1}', '{"c": 2}')
            assert result == (False, ["Expected value for c is 1 but found 2"])
        """
        try:
            if not expected_json:
                raise ValueError("expected_json cannot be null or empty.")
            if not actual_json:
                raise ValueError("actual_json cannot be null or empty.")

            if ignore_keys is None:
                ignore_keys = []
            elif not isinstance(ignore_keys, list):
                raise TypeError("ignore_keys must be a list.")

            if not isinstance(ignore_extra, bool):
                raise TypeError("ignore_extra must be a boolean.")

            obj_parse_data = ParseJsonData()
            result = obj_parse_data.compare_json(
                expected_json, actual_json, ignore_keys, ignore_extra
            )
            return result

        except (ValueError, json.JSONDecodeError) as e:
            self.logger.exception("Error in comparing two JSON structures: %s", e)
            raise ValueError(f"Error comparing JSON objects: {e}") from e

    def convert_json_to_xml(self, pjson: str | dict) -> str:
        """Converts a JSON string/dict to an XML string.

        Args:
            pjson: The JSON string/dict to convert.

        Returns:
            The XML string.

        Raises:
            ValueError: If the input JSON is invalid.
        """
        if not pjson:
            raise ValueError("pjson cannot be null or empty.")
        try:
            obj_parse_data = ParseJsonData()
            return obj_parse_data.convert_json_to_xml(pjson)
        except Exception as e:
            self.logger.exception("Error in provided json to xml: %s", e)
            raise e

    def get_all_keys(self, pjson: str | dict) -> list[str]:
        """Extracts all keys from a nested JSON dictionary as a list.

        Args:
            pjson: The JSON data (string or dictionary).

        Returns:
            A list of all keys found in the JSON data.

        Raises:
            ValueError: If the input JSON data is invalid
        """
        if not pjson:
            raise ValueError("pjson cannot be null or empty.")
        try:
            obj_parse_data = ParseJsonData()
            return obj_parse_data.get_all_keys(pjson)
        except Exception as e:
            self.logger.exception("Error in extracting keys from a nested JSON dictionary: %s", e)
            raise e

    def key_exists(self, json_data: str | dict, key: str) -> bool:
        """Checks if a key exists in the JSON data.

        Args:
            json_data: The JSON data (string or dictionary).
            key: The key to check for.

        Returns:
            True if the key exists, False otherwise.

        Raises:
            ValueError: If the input JSON data is invalid or the key is empty.
        """
        if not json_data:
            raise ValueError("json_data cannot be empty.")
        if not key:
            raise ValueError("key cannot be empty.")
        try:
            obj_parse_data = ParseJsonData()
            return obj_parse_data.key_exists(json_data, key)
        except Exception as e:
            self.logger.exception("Error in checking if key exists in the JSON data: %s", e)
            raise e

    def get_occurrence_of_key(self, json_data: str | dict, key: str) -> int:
        """Counts the occurrences of a key in the JSON data.

        Args:
            json_data: The JSON data (string or dictionary).
            key: The key to count occurrences of.

        Returns:
            The number of occurrences of the key.

        Raises:
            ValueError: If the input JSON data is invalid or the key is empty.
        """
        if not json_data:
            raise ValueError("json_data cannot be empty.")
        if not key:
            raise ValueError("key cannot be empty.")
        try:
            obj_parse_data = ParseJsonData()
            return obj_parse_data.get_occurrence_of_key(json_data, key)
        except Exception as e:
            self.logger.exception("Error in finding occurrences of a key in the JSON data: %s", e)
            raise e

    def get_key_path_value(self, **kwargs: Any) -> Any:
        """Extracts the value at the specified key path from the JSON data.

        Kwargs:
            json: The JSON data (string or dictionary).
            keyPath: The path to the key, using the specified delimiter.
            keyPathType: Either "absolute" or "relative" (default: "absolute").
            delimiter: The delimiter used in the key path (default: "/").
            key: The key to retrieve the value for when using relative key paths.

        Returns:
            The value associated with the key path.

        Raises:
            ValueError: If required arguments are missing, invalid, or the key path is not found.
            json.JSONDecodeError: If the JSON data is invalid.

        Examples:
            get_key_path_value(json='json data',
                               keyPath='node1/node2/key',
                               keyPathType='absolute')
            get_key_path_value(json='json data',
                               keyPath='node1/node2',
                               keyPathType='relative',
                               key='key')
        """
        try:
            if "json" not in kwargs:
                self.logger.info("No json argument provided")
                raise ValueError("json argument is required.")
            if "keyPath" not in kwargs:
                self.logger.info("No keyPath argument provided")
                raise ValueError("keyPath argument is required.")
            if "keyPathType" not in kwargs:
                self.logger.info("No keyPathType argument provided")
                raise ValueError("keyPathType argument is required.")
            obj_parse_data = ParseJsonData()
            return obj_parse_data.get_value_from_key_path(**kwargs)
        except Exception as e:
            self.logger.exception("Error in extracting the value at the specified key path: %s", e)
            raise e

compare_json(expected_json, actual_json, ignore_keys=None, ignore_extra=False)

Compares two JSON structures (strings or dictionaries).

Parameters:

Name Type Description Default
expected_json str | dict

The expected JSON data (string or dictionary).

required
actual_json str | dict

The actual JSON data (string or dictionary).

required
ignore_keys list[str] | None

A list of keys to ignore during comparison (default: None).

None
ignore_extra bool

Whether to ignore extra keys in actual_json (default: False).

False

Returns:

Type Description
bool | tuple[bool, list[str]]

True if the JSON structures are equal (considering ignore_keys and ignore_extra),

bool | tuple[bool, list[str]]

otherwise a tuple containing False and a list of mismatches.

Raises:

Type Description
ValueError

If the input JSON data is invalid.

Examples:

Comparing two JSON strings

result = compare_json('{"a": 1, "b": 2}', '{"a": 1, "b": 2}') assert result is True

Comparing two dictionaries

result = compare_json({"a": 1, "b": 2}, {"a": 1, "b": 2}) assert result is True

Ignoring specific keys

result = compare_json('{"a": 1, "b": 2}', '{"a": 1, "b": 3}', ignore_keys=["b"]) assert result is True

Ignoring extra keys

result = compare_json('{"a": 1}', '{"a": 1, "b": 2}', ignore_extra=True) assert result is True

Mismatch example

result = compare_json('{"c": 1}', '{"c": 2}') assert result == (False, ["Expected value for c is 1 but found 2"])

Source code in libs\cafex_api\src\cafex_api\response_parser_json.py
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
def compare_json(
    self,
    expected_json: str | dict,
    actual_json: str | dict,
    ignore_keys: list[str] | None = None,
    ignore_extra: bool = False,
) -> bool | tuple[bool, list[str]]:
    """Compares two JSON structures (strings or dictionaries).

    Args:
        expected_json: The expected JSON data (string or dictionary).
        actual_json: The actual JSON data (string or dictionary).
        ignore_keys: A list of keys to ignore during comparison (default: None).
        ignore_extra: Whether to ignore extra keys in actual_json (default: False).

    Returns:
        True if the JSON structures are equal (considering ignore_keys and ignore_extra),
        otherwise a tuple containing False and a list of mismatches.

    Raises:
        ValueError: If the input JSON data is invalid.

    Examples:
        # Comparing two JSON strings
        result = compare_json('{"a": 1, "b": 2}', '{"a": 1, "b": 2}')
        assert result is True

        # Comparing two dictionaries
        result = compare_json({"a": 1, "b": 2}, {"a": 1, "b": 2})
        assert result is True

        # Ignoring specific keys
        result = compare_json('{"a": 1, "b": 2}', '{"a": 1, "b": 3}', ignore_keys=["b"])
        assert result is True

        # Ignoring extra keys
        result = compare_json('{"a": 1}', '{"a": 1, "b": 2}', ignore_extra=True)
        assert result is True

        # Mismatch example
        result = compare_json('{"c": 1}', '{"c": 2}')
        assert result == (False, ["Expected value for c is 1 but found 2"])
    """
    try:
        if not expected_json:
            raise ValueError("expected_json cannot be null or empty.")
        if not actual_json:
            raise ValueError("actual_json cannot be null or empty.")

        if ignore_keys is None:
            ignore_keys = []
        elif not isinstance(ignore_keys, list):
            raise TypeError("ignore_keys must be a list.")

        if not isinstance(ignore_extra, bool):
            raise TypeError("ignore_extra must be a boolean.")

        obj_parse_data = ParseJsonData()
        result = obj_parse_data.compare_json(
            expected_json, actual_json, ignore_keys, ignore_extra
        )
        return result

    except (ValueError, json.JSONDecodeError) as e:
        self.logger.exception("Error in comparing two JSON structures: %s", e)
        raise ValueError(f"Error comparing JSON objects: {e}") from e

convert_json_to_xml(pjson)

Converts a JSON string/dict to an XML string.

Parameters:

Name Type Description Default
pjson str | dict

The JSON string/dict to convert.

required

Returns:

Type Description
str

The XML string.

Raises:

Type Description
ValueError

If the input JSON is invalid.

Source code in libs\cafex_api\src\cafex_api\response_parser_json.py
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
def convert_json_to_xml(self, pjson: str | dict) -> str:
    """Converts a JSON string/dict to an XML string.

    Args:
        pjson: The JSON string/dict to convert.

    Returns:
        The XML string.

    Raises:
        ValueError: If the input JSON is invalid.
    """
    if not pjson:
        raise ValueError("pjson cannot be null or empty.")
    try:
        obj_parse_data = ParseJsonData()
        return obj_parse_data.convert_json_to_xml(pjson)
    except Exception as e:
        self.logger.exception("Error in provided json to xml: %s", e)
        raise e

get_all_keys(pjson)

Extracts all keys from a nested JSON dictionary as a list.

Parameters:

Name Type Description Default
pjson str | dict

The JSON data (string or dictionary).

required

Returns:

Type Description
list[str]

A list of all keys found in the JSON data.

Raises:

Type Description
ValueError

If the input JSON data is invalid

Source code in libs\cafex_api\src\cafex_api\response_parser_json.py
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
def get_all_keys(self, pjson: str | dict) -> list[str]:
    """Extracts all keys from a nested JSON dictionary as a list.

    Args:
        pjson: The JSON data (string or dictionary).

    Returns:
        A list of all keys found in the JSON data.

    Raises:
        ValueError: If the input JSON data is invalid
    """
    if not pjson:
        raise ValueError("pjson cannot be null or empty.")
    try:
        obj_parse_data = ParseJsonData()
        return obj_parse_data.get_all_keys(pjson)
    except Exception as e:
        self.logger.exception("Error in extracting keys from a nested JSON dictionary: %s", e)
        raise e

get_key_path_value(**kwargs)

Extracts the value at the specified key path from the JSON data.

Kwargs

json: The JSON data (string or dictionary). keyPath: The path to the key, using the specified delimiter. keyPathType: Either "absolute" or "relative" (default: "absolute"). delimiter: The delimiter used in the key path (default: "/"). key: The key to retrieve the value for when using relative key paths.

Returns:

Type Description
Any

The value associated with the key path.

Raises:

Type Description
ValueError

If required arguments are missing, invalid, or the key path is not found.

JSONDecodeError

If the JSON data is invalid.

Examples:

get_key_path_value(json='json data', keyPath='node1/node2/key', keyPathType='absolute') get_key_path_value(json='json data', keyPath='node1/node2', keyPathType='relative', key='key')

Source code in libs\cafex_api\src\cafex_api\response_parser_json.py
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
def get_key_path_value(self, **kwargs: Any) -> Any:
    """Extracts the value at the specified key path from the JSON data.

    Kwargs:
        json: The JSON data (string or dictionary).
        keyPath: The path to the key, using the specified delimiter.
        keyPathType: Either "absolute" or "relative" (default: "absolute").
        delimiter: The delimiter used in the key path (default: "/").
        key: The key to retrieve the value for when using relative key paths.

    Returns:
        The value associated with the key path.

    Raises:
        ValueError: If required arguments are missing, invalid, or the key path is not found.
        json.JSONDecodeError: If the JSON data is invalid.

    Examples:
        get_key_path_value(json='json data',
                           keyPath='node1/node2/key',
                           keyPathType='absolute')
        get_key_path_value(json='json data',
                           keyPath='node1/node2',
                           keyPathType='relative',
                           key='key')
    """
    try:
        if "json" not in kwargs:
            self.logger.info("No json argument provided")
            raise ValueError("json argument is required.")
        if "keyPath" not in kwargs:
            self.logger.info("No keyPath argument provided")
            raise ValueError("keyPath argument is required.")
        if "keyPathType" not in kwargs:
            self.logger.info("No keyPathType argument provided")
            raise ValueError("keyPathType argument is required.")
        obj_parse_data = ParseJsonData()
        return obj_parse_data.get_value_from_key_path(**kwargs)
    except Exception as e:
        self.logger.exception("Error in extracting the value at the specified key path: %s", e)
        raise e

get_key_value(**kwargs)

Extracts the value(s) of thr key from the JSON data, optionally searching nested structures.

Kwargs

json: The JSON data (string or dictionary). key: The key to retrieve the value for. nested: Whether to search for the key in nested structures (default: False).

Returns:

Type Description
Any

The value associated with the key

Any

The list of values if nested is True and multiple keys are found.

Raises:

Type Description
ValueError

If required arguments are missing or invalid.

JSONDecodeError

If the JSON data is invalid.

Examples:

response_parser.get_key_value(json=dict_response, key=item)

searches nested keys and gets all the lists

self.response_parser.get_key_value(json=dict_response, key=item, nested=True)

Source code in libs\cafex_api\src\cafex_api\response_parser_json.py
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
def get_key_value(self, **kwargs) -> Any:
    """Extracts the value(s) of thr key from the JSON data, optionally
    searching nested structures.

    Kwargs:
        json: The JSON data (string or dictionary).
        key: The key to retrieve the value for.
        nested: Whether to search for the key in nested structures (default: False).

    Returns:
        The value associated with the key
        The list of values if nested is True and multiple keys are found.

    Raises:
        ValueError: If required arguments are missing or invalid.
        json.JSONDecodeError: If the JSON data is invalid.

    Examples:
        # gets the first key Item. no nested search
        response_parser.get_key_value(json=dict_response, key=item)
        # searches nested keys and gets all the lists
        self.response_parser.get_key_value(json=dict_response, key=item, nested=True)
    """
    try:
        if "json" not in kwargs:
            self.logger.info("No 'json' parameter Passed")
            raise ValueError("'json' parameter is required.")
        if "key" not in kwargs:
            self.logger.info("No 'key' parameter Passed")
            raise ValueError("'key' parameter is required.")

        json_data = kwargs.get("json")
        key = kwargs.get("key")
        nested = kwargs.get("nested", False)

        if not json_data:
            raise ValueError("The 'json_data' parameter cannot be null or empty.")
        if not key:
            raise ValueError("The 'key' parameter cannot be null or empty.")
        if not isinstance(nested, bool):
            raise ValueError("The 'nested' parameter must be a boolean")

        obj_parse_data = ParseJsonData()
        return obj_parse_data.get_value_of_key(json_data, key, nested)
    except Exception as e:
        self.logger.exception("Error in extracting the value(s) of the specified key: %s", e)
        raise e

get_occurrence_of_key(json_data, key)

Counts the occurrences of a key in the JSON data.

Parameters:

Name Type Description Default
json_data str | dict

The JSON data (string or dictionary).

required
key str

The key to count occurrences of.

required

Returns:

Type Description
int

The number of occurrences of the key.

Raises:

Type Description
ValueError

If the input JSON data is invalid or the key is empty.

Source code in libs\cafex_api\src\cafex_api\response_parser_json.py
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
def get_occurrence_of_key(self, json_data: str | dict, key: str) -> int:
    """Counts the occurrences of a key in the JSON data.

    Args:
        json_data: The JSON data (string or dictionary).
        key: The key to count occurrences of.

    Returns:
        The number of occurrences of the key.

    Raises:
        ValueError: If the input JSON data is invalid or the key is empty.
    """
    if not json_data:
        raise ValueError("json_data cannot be empty.")
    if not key:
        raise ValueError("key cannot be empty.")
    try:
        obj_parse_data = ParseJsonData()
        return obj_parse_data.get_occurrence_of_key(json_data, key)
    except Exception as e:
        self.logger.exception("Error in finding occurrences of a key in the JSON data: %s", e)
        raise e

key_exists(json_data, key)

Checks if a key exists in the JSON data.

Parameters:

Name Type Description Default
json_data str | dict

The JSON data (string or dictionary).

required
key str

The key to check for.

required

Returns:

Type Description
bool

True if the key exists, False otherwise.

Raises:

Type Description
ValueError

If the input JSON data is invalid or the key is empty.

Source code in libs\cafex_api\src\cafex_api\response_parser_json.py
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
def key_exists(self, json_data: str | dict, key: str) -> bool:
    """Checks if a key exists in the JSON data.

    Args:
        json_data: The JSON data (string or dictionary).
        key: The key to check for.

    Returns:
        True if the key exists, False otherwise.

    Raises:
        ValueError: If the input JSON data is invalid or the key is empty.
    """
    if not json_data:
        raise ValueError("json_data cannot be empty.")
    if not key:
        raise ValueError("key cannot be empty.")
    try:
        obj_parse_data = ParseJsonData()
        return obj_parse_data.key_exists(json_data, key)
    except Exception as e:
        self.logger.exception("Error in checking if key exists in the JSON data: %s", e)
        raise e