From 40f642b275bb1892a271584b0717171f059f8e26 Mon Sep 17 00:00:00 2001 From: JacobAndrewSmith92 Date: Thu, 14 Mar 2024 14:53:48 -0500 Subject: [PATCH] fix(exceptions): Update headers.get to check 'Retry-After' (#130) * bug: Upate retry-after header to match API dictionary looks up are case sensitive. Since we return the header as Retry-After we need to have the .get match * write simple test to verify * remove support for 3.7 - add support for 3.11 & 3.12 * build release version to 3.11 --- .travis.yml | 5 +++-- smartcar/exception.py | 4 ++-- smartcar/vehicle.py | 12 ++++++------ tests/e2e/test_exception.py | 15 +++++++++++++++ 4 files changed, 26 insertions(+), 10 deletions(-) diff --git a/.travis.yml b/.travis.yml index da27834e..0dcb2cd2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,10 +9,11 @@ addons: language: python python: - - '3.7' - '3.8' - '3.9' - '3.10' + - '3.11' + - '3.12' if: tag IS blank # do not build tags @@ -35,7 +36,7 @@ script: jobs: include: - stage: publish - python: '3.9' + python: '3.11' services: [] addons: firefox: 'skip' diff --git a/smartcar/exception.py b/smartcar/exception.py index 8bfd4f35..825df577 100644 --- a/smartcar/exception.py +++ b/smartcar/exception.py @@ -77,7 +77,7 @@ def exception_factory(status_code: int, headers: dict, body: str): # v2.0 elif response.get("type"): # Set retry_after only for Vehicle Rate Limit errors - if headers.get("retry-after") is not None: + if headers.get("Retry-After") is not None: return SmartcarException( status_code=response.get("statusCode"), request_id=response.get("requestId"), @@ -87,7 +87,7 @@ def exception_factory(status_code: int, headers: dict, body: str): doc_url=response.get("docURL"), resolution=response.get("resolution"), detail=response.get("detail"), - retry_after=headers.get("retry-after"), + retry_after=headers.get("Retry-After"), ) else: return SmartcarException( diff --git a/smartcar/vehicle.py b/smartcar/vehicle.py index 60e19a44..392b5ec0 100644 --- a/smartcar/vehicle.py +++ b/smartcar/vehicle.py @@ -443,9 +443,9 @@ def batch(self, paths: List[str]) -> namedtuple: "sc-request-id" ) # use lambda default args to avoid issues with closures - batch_dict[ - attribute - ] = lambda p=path, r=res_dict: types.select_named_tuple(p, r) + batch_dict[attribute] = ( + lambda p=path, r=res_dict: types.select_named_tuple(p, r) + ) else: # if individual response is erroneous, attach a lambda that returns a SmartcarException def _attribute_raise_exception(smartcar_exception): @@ -455,9 +455,9 @@ def _attribute_raise_exception(smartcar_exception): headers = response.headers body = json.dumps(res_dict.get("body")) sc_exception = sce.exception_factory(code, headers, body) - batch_dict[ - attribute - ] = lambda e=sc_exception: _attribute_raise_exception(e) + batch_dict[attribute] = ( + lambda e=sc_exception: _attribute_raise_exception(e) + ) # STEP 3 - Attach Meta to batch_dict batch_dict["meta"] = types.build_meta(response.headers) diff --git a/tests/e2e/test_exception.py b/tests/e2e/test_exception.py index c3ecc12a..8f63cdbf 100644 --- a/tests/e2e/test_exception.py +++ b/tests/e2e/test_exception.py @@ -148,3 +148,18 @@ def test_json_cant_be_parsed(): assert e.message == "diggity" assert e.status_code == 900 assert e.type == "SDK_ERROR" + + +def test_retry_after_found(): + """ + test that we can get the retry_after amount + """ + try: + raise exception_factory( + 429, + {"Retry-After": 5000, "Content-Type": "application/json"}, + '{"statusCode":429,"type":"RATE_LIMIT","code":"Vehicle","resolution":{"type":"RETRY_LATER"},"requestId":"e0027f5f-4411-4247-a54d-e34c157d84c1"}', + ) + except Exception as e: + assert isinstance(e, SmartcarException) + assert e.retry_after == 5000