From 20bf28de9c478f5718d10f38a026d1f027769aa6 Mon Sep 17 00:00:00 2001 From: TNA-Allan Date: Fri, 31 Jan 2025 13:55:06 +0000 Subject: [PATCH 1/3] FIX:JSONDecodeError --- etna/ciim/client.py | 24 +++++++++++---- etna/ciim/tests/test_client.py | 54 ++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 5 deletions(-) diff --git a/etna/ciim/client.py b/etna/ciim/client.py index ea9120427..bcd0e106d 100755 --- a/etna/ciim/client.py +++ b/etna/ciim/client.py @@ -298,7 +298,8 @@ def fetch( response = self.make_request(f"{self.base_url}/fetch", params=params) # Convert the HTTP response to a Python dict - response_data = response.json() + response_data = self.decode_json_response(response) + print(f"response_data....{response_data}") # Convert the Python dict to a ResultList result_list = self.resultlist_from_response(response_data) @@ -399,7 +400,7 @@ def search( response = self.make_request(f"{self.base_url}/search", params=params) # Convert the HTTP response to a Python dict - response_data = response.json() + response_data = self.decode_json_response(response) # Pull out the separate ES responses bucket_counts_data, results_data = response_data["responses"] @@ -457,7 +458,7 @@ def search_all( response = self.make_request(f"{self.base_url}/searchAll", params=params) # Convert the HTTP response to a Python dict - response_data = response.json() + response_data = self.decode_json_response(response) # The API returns a series of ES 'responses', with results for each 'bucket'. # Each of these responses is converted to it's own `ResultList`, and the collective @@ -521,7 +522,7 @@ def search_unified( response = self.make_request(f"{self.base_url}/searchUnified", params=params) # Convert the HTTP response to a Python dict - response_data = response.json() + response_data = self.decode_json_response(response) # The API returns a single ES response for this endpoint, which can be directly converted # to a ResultList. @@ -570,7 +571,7 @@ def fetch_all( response = self.make_request(f"{self.base_url}/fetchAll", params=params) # Convert the HTTP response to a Python dict - response_data = response.json() + response_data = self.decode_json_response(response) # The API returns a single ES response for this endpoint, which can be directly converted # to a ResultList. @@ -597,6 +598,19 @@ def make_request( self._raise_for_status(response) return response + def decode_json_response(self, response): + """Returns decoded JSON data using the built-in json decoder""" + try: + print(f"decode_json_response............................1") + return response.json() + print(f"decode_json_response............................2") + except ValueError as e: + print(f"decode_json_response............................Error") + # log exception value with response body + logger.warning(f"{str(e)}:Response body:{response.text}") + # suppress double exception raising, keeping original exception available + raise Exception(e) from None + def _raise_for_status(self, response: requests.Response) -> None: """Raise custom error for any requests.HTTPError raised for a request. diff --git a/etna/ciim/tests/test_client.py b/etna/ciim/tests/test_client.py index 7db8b987b..0f0b7ca23 100644 --- a/etna/ciim/tests/test_client.py +++ b/etna/ciim/tests/test_client.py @@ -1174,3 +1174,57 @@ def test_valid_response(self): response = self.records_client.fetch_all() self.assertIsInstance(response, ResultList) self.assertEqual(response.hits, ()) + + + +class DecodeJSONResponseTest(SimpleTestCase): + def setUp(self): + self.records_client = get_records_client() + + @responses.activate + def test_decode_json_response_fetch(self): + + responses.add( + responses.GET, + f"{settings.CLIENT_BASE_URL}/fetch", + status=204, # no content + body="", + content_type="application/json", + ) + + with self.assertLogs("etna.ciim.client", level="WARNING") as lc: + with self.assertRaisesMessage( + Exception, "Expecting value: line 1 column 1 (char 0)" + ): + self.records_client.fetch() + + self.assertIn( + "WARNING:etna.ciim.client:" + "Expecting value: line 1 column 1 (char 0):" + "Response body:", + lc.output, + ) + + @responses.activate + def test_decode_json_response_search(self): + + responses.add( + responses.GET, + f"{settings.CLIENT_BASE_URL}/search", + status=204, # no content + body="", + content_type="application/json", + ) + + with self.assertLogs("etna.ciim.client", level="WARNING") as lc: + with self.assertRaisesMessage( + Exception, "Expecting value: line 1 column 1 (char 0)" + ): + self.records_client.search() + + self.assertIn( + "WARNING:etna.ciim.client:" + "Expecting value: line 1 column 1 (char 0):" + "Response body:", + lc.output, + ) \ No newline at end of file From 328c9aab20d893867b076e5fd6bc377577bc0964 Mon Sep 17 00:00:00 2001 From: TNA-Allan Date: Fri, 31 Jan 2025 13:57:14 +0000 Subject: [PATCH 2/3] FIX:JSONDecodeError - remove print --- etna/ciim/client.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/etna/ciim/client.py b/etna/ciim/client.py index bcd0e106d..99d388da7 100755 --- a/etna/ciim/client.py +++ b/etna/ciim/client.py @@ -299,7 +299,6 @@ def fetch( # Convert the HTTP response to a Python dict response_data = self.decode_json_response(response) - print(f"response_data....{response_data}") # Convert the Python dict to a ResultList result_list = self.resultlist_from_response(response_data) @@ -601,11 +600,8 @@ def make_request( def decode_json_response(self, response): """Returns decoded JSON data using the built-in json decoder""" try: - print(f"decode_json_response............................1") return response.json() - print(f"decode_json_response............................2") except ValueError as e: - print(f"decode_json_response............................Error") # log exception value with response body logger.warning(f"{str(e)}:Response body:{response.text}") # suppress double exception raising, keeping original exception available From 3a267e79f30e5f85f9b11af60c2dcca4db8586db Mon Sep 17 00:00:00 2001 From: TNA-Allan Date: Fri, 31 Jan 2025 14:10:08 +0000 Subject: [PATCH 3/3] FIX:JSONDecodeError - update error level --- etna/ciim/client.py | 2 +- etna/ciim/tests/test_client.py | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/etna/ciim/client.py b/etna/ciim/client.py index 99d388da7..e54981960 100755 --- a/etna/ciim/client.py +++ b/etna/ciim/client.py @@ -603,7 +603,7 @@ def decode_json_response(self, response): return response.json() except ValueError as e: # log exception value with response body - logger.warning(f"{str(e)}:Response body:{response.text}") + logger.error(f"{str(e)}:Response body:{response.text}") # suppress double exception raising, keeping original exception available raise Exception(e) from None diff --git a/etna/ciim/tests/test_client.py b/etna/ciim/tests/test_client.py index 0f0b7ca23..6dabe916f 100644 --- a/etna/ciim/tests/test_client.py +++ b/etna/ciim/tests/test_client.py @@ -1192,14 +1192,14 @@ def test_decode_json_response_fetch(self): content_type="application/json", ) - with self.assertLogs("etna.ciim.client", level="WARNING") as lc: + with self.assertLogs("etna.ciim.client", level="ERROR") as lc: with self.assertRaisesMessage( Exception, "Expecting value: line 1 column 1 (char 0)" ): self.records_client.fetch() self.assertIn( - "WARNING:etna.ciim.client:" + "ERROR:etna.ciim.client:" "Expecting value: line 1 column 1 (char 0):" "Response body:", lc.output, @@ -1216,14 +1216,14 @@ def test_decode_json_response_search(self): content_type="application/json", ) - with self.assertLogs("etna.ciim.client", level="WARNING") as lc: + with self.assertLogs("etna.ciim.client", level="ERROR") as lc: with self.assertRaisesMessage( Exception, "Expecting value: line 1 column 1 (char 0)" ): self.records_client.search() self.assertIn( - "WARNING:etna.ciim.client:" + "ERROR:etna.ciim.client:" "Expecting value: line 1 column 1 (char 0):" "Response body:", lc.output,