From 9c28470b2e2fa18f90a1bc30d25c5536b1515e61 Mon Sep 17 00:00:00 2001 From: Carlos Villavicencio Date: Mon, 5 May 2025 15:00:08 -0500 Subject: [PATCH 1/6] Prevent unexpected retries on error --- shotgun_api3/shotgun.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/shotgun_api3/shotgun.py b/shotgun_api3/shotgun.py index b682e87e..3e9cfeae 100644 --- a/shotgun_api3/shotgun.py +++ b/shotgun_api3/shotgun.py @@ -3938,11 +3938,10 @@ def _make_call(self, verb, path, body, headers): if attempt == max_rpc_attempts: LOG.debug("Request failed. Giving up after %d attempts." % attempt) raise - except Exception: + except Exception as e: self._close_connection() - if attempt == max_rpc_attempts: - LOG.debug("Request failed. Giving up after %d attempts." % attempt) - raise + LOG.debug(f"Request failed. Reason: {e}") + raise LOG.debug( "Request failed, attempt %d of %d. Retrying in %.2f seconds..." From e80ea2ee81ecbdd85bc0df01bcab4fd781c6e75d Mon Sep 17 00:00:00 2001 From: Carlos Villavicencio Date: Mon, 5 May 2025 16:14:55 -0500 Subject: [PATCH 2/6] Fix tests --- tests/test_api.py | 36 +----------------------------------- tests/test_client.py | 10 +--------- 2 files changed, 2 insertions(+), 44 deletions(-) diff --git a/tests/test_api.py b/tests/test_api.py index 788c9751..407df92f 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -2223,42 +2223,8 @@ def test_make_call_retry(self, mock_request): self.assertEqual(cm2.exception.args[0], "not working") log_content = "\n".join(cm1.output) - for i in [1, 2]: - self.assertIn( - f"Request failed, attempt {i} of 3. Retrying", - log_content, - ) - self.assertIn( - "Request failed. Giving up after 3 attempts.", - log_content, - ) - - # Then, make the exception happening only once and prove the - # retry works - def my_side_effect(*args, **kwargs): - try: - if my_side_effect.counter < 1: - raise Exception("not working") - - return mock.DEFAULT - finally: - my_side_effect.counter += 1 - - my_side_effect.counter = 0 - mock_request.side_effect = my_side_effect - with self.assertLogs("shotgun_api3", level="DEBUG") as cm: - self.assertIsInstance( - self.sg.info(), - dict, - ) - - log_content = "\n".join(cm.output) self.assertIn( - "Request failed, attempt 1 of 3. Retrying", - log_content, - ) - self.assertNotIn( - "Request failed, attempt 2 of 3. Retrying", + "Request failed. Reason: not working", log_content, ) diff --git a/tests/test_client.py b/tests/test_client.py index e29c6158..ec50dd3b 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -330,17 +330,9 @@ def test_network_retry(self): with mock.patch("time.sleep") as mock_sleep: self.assertRaises(httplib2.HttpLib2Error, self.sg.info) self.assertTrue( - self.sg.config.max_rpc_attempts == self.sg._http_request.call_count, + self.sg._http_request.call_count == 1, "Call is repeated", ) - # Ensure that sleep was called with the retry interval between each attempt - attempt_interval = self.sg.config.rpc_attempt_interval / 1000.0 - calls = [mock.callargs(((attempt_interval,), {}))] - calls *= self.sg.config.max_rpc_attempts - 1 - self.assertTrue( - mock_sleep.call_args_list == calls, - "Call is repeated at correct interval.", - ) def test_set_retry_interval(self): """Setting the retry interval through parameter and environment variable works.""" From 63484fe75b18b000937b3cd7cf70da6f744e7920 Mon Sep 17 00:00:00 2001 From: Carlos Villavicencio <123113322+carlos-villavicencio-adsk@users.noreply.github.com> Date: Wed, 7 May 2025 13:29:30 -0500 Subject: [PATCH 3/6] Update shotgun_api3/shotgun.py Co-authored-by: Julien Langlois <16244608+julien-lang@users.noreply.github.com> --- shotgun_api3/shotgun.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shotgun_api3/shotgun.py b/shotgun_api3/shotgun.py index 3e9cfeae..33f6d73b 100644 --- a/shotgun_api3/shotgun.py +++ b/shotgun_api3/shotgun.py @@ -3940,7 +3940,7 @@ def _make_call(self, verb, path, body, headers): raise except Exception as e: self._close_connection() - LOG.debug(f"Request failed. Reason: {e}") + LOG.debug(f"Request failed. Reason: {e}", exc_info=True) raise LOG.debug( From 180f025d2b7791fff3f5b31817b8429f068f9c09 Mon Sep 17 00:00:00 2001 From: Carlos Villavicencio Date: Wed, 7 May 2025 16:37:12 -0500 Subject: [PATCH 4/6] Packaging for v3.8.3-beta1 --- HISTORY.rst | 7 +++++++ setup.py | 2 +- shotgun_api3/shotgun.py | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/HISTORY.rst b/HISTORY.rst index 54b30f21..3efc249a 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -4,6 +4,13 @@ Flow Production Tracking Python API Changelog Here you can see the full list of changes between each Python API release. +v3.8.3-beta1 (2025 May 7) +========================== + +- We don't want to retry on a general exceptions (e.g. Timeout or remote disconnection) + because we might send a resource modification request (create, batch create, etc) and + we can end up duplicating things. + v3.8.2 (2025 Mar 11) ==================== diff --git a/setup.py b/setup.py index cf3304f9..4370c978 100644 --- a/setup.py +++ b/setup.py @@ -20,7 +20,7 @@ setup( name="shotgun_api3", - version="3.8.2", + version="3.8.3-beta1", description="Flow Production Tracking Python API", long_description=readme, author="Autodesk", diff --git a/shotgun_api3/shotgun.py b/shotgun_api3/shotgun.py index 33f6d73b..52dad046 100644 --- a/shotgun_api3/shotgun.py +++ b/shotgun_api3/shotgun.py @@ -122,7 +122,7 @@ def _is_mimetypes_broken(): # ---------------------------------------------------------------------------- # Version -__version__ = "3.8.2" +__version__ = "3.8.3-beta1" # ---------------------------------------------------------------------------- # Errors From 864080c276c4f7c6acf1bc20006227265a192b5b Mon Sep 17 00:00:00 2001 From: Carlos Villavicencio Date: Fri, 13 Jun 2025 12:42:08 -0500 Subject: [PATCH 5/6] Fix typo --- HISTORY.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HISTORY.rst b/HISTORY.rst index e480d58d..d1c34185 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -7,7 +7,7 @@ Here you can see the full list of changes between each Python API release. v3.8.5 (2025 Xxx X) =================== -- We don't want to retry on a general exceptions (e.g. Timeout or remote disconnection) +- We don't want to retry on general exceptions (e.g. Timeout or remote disconnection) because we might send a resource modification request (create, batch create, etc) and we can end up duplicating things. From 6119380206803f7bd16a8c57456fef55e2eca566 Mon Sep 17 00:00:00 2001 From: Carlos Villavicencio <123113322+carlos-villavicencio-adsk@users.noreply.github.com> Date: Sat, 14 Jun 2025 08:42:13 -0500 Subject: [PATCH 6/6] Update HISTORY.rst Co-authored-by: Julien Langlois <16244608+julien-lang@users.noreply.github.com> --- HISTORY.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HISTORY.rst b/HISTORY.rst index d1c34185..c19b61fe 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -7,7 +7,7 @@ Here you can see the full list of changes between each Python API release. v3.8.5 (2025 Xxx X) =================== -- We don't want to retry on general exceptions (e.g. Timeout or remote disconnection) +- We don't want to retry on general exceptions (e.g. timeout or remote disconnection) because we might send a resource modification request (create, batch create, etc) and we can end up duplicating things.