From f9acf430eac56b25a39bba0198ebb0e46fb5e66b Mon Sep 17 00:00:00 2001 From: Richard A Date: Sat, 25 Mar 2023 19:57:37 +0400 Subject: [PATCH 1/2] Update rest_client.py delete 'JSONDecodeError' Update rest_client.py c c c c Revert "c" This reverts commit 691317793cf5e7baa66f2f11ea7996ebeef87bb3. Revert "c" This reverts commit a61a0e94203fd71d3b2fed329f707911582f49f1. Revert "c" This reverts commit 1d2e8100905c97581dd4447155dffc03e6e3f097. Revert "c" This reverts commit 0b88f05725577876600b5171aaf694def6baa0f2. Revert "Update rest_client.py" This reverts commit 7110a76e2ee20c0bde0b2a3a3c0f04941047bfcb. Revert "Update rest_client.py" This reverts commit 7a4510f2982be499fba59a2a8fe0c408750d37b0. add handling if no return body present --- src/valr_python/rest_client.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/valr_python/rest_client.py b/src/valr_python/rest_client.py index 8efce2b..a2432ff 100644 --- a/src/valr_python/rest_client.py +++ b/src/valr_python/rest_client.py @@ -77,12 +77,15 @@ def _do(self, method: str, path: str, data: Optional[Dict] = None, params: Optio try: res.raise_for_status() - e = res.json() - self._raise_for_api_error(e) - # provide warning with bundled response dict for incomplete transactions - if res.status_code == 202: - warnings.warn(IncompleteOrderWarning(data=e, message="Order processing incomplete")) - return e + if res.text: + e = res.json() + self._raise_for_api_error(e) + # provide warning with bundled response dict for incomplete transactions + if res.status_code == 202: + warnings.warn(IncompleteOrderWarning(data=e, message="Order processing incomplete")) + return e + else: + return res.raise_for_status() except HTTPError as he: print(he) if res.status_code == 429: From 27fe66520d2a4418c7c2b00b752c307edef0edec Mon Sep 17 00:00:00 2001 From: Richard A Date: Tue, 28 Mar 2023 11:20:43 +0400 Subject: [PATCH 2/2] add handling if no return body present --- src/valr_python/rest_base.py | 2 +- src/valr_python/rest_client.py | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/valr_python/rest_base.py b/src/valr_python/rest_base.py index 703f7af..b18f8a6 100644 --- a/src/valr_python/rest_base.py +++ b/src/valr_python/rest_base.py @@ -1019,4 +1019,4 @@ def delete_order(self, currency_pair: Union[str, CurrencyPair], order_id: str = data["orderId"] = order_id else: data["customerOrderId"] = customer_order_id - return self._do('DELETE', '/v1/orders/order', data=data, is_authenticated=True, subaccount_id=subaccount_id) + return self._do_delete('DELETE', '/v1/orders/order', data=data, is_authenticated=True, subaccount_id=subaccount_id) diff --git a/src/valr_python/rest_client.py b/src/valr_python/rest_client.py index a2432ff..0869399 100644 --- a/src/valr_python/rest_client.py +++ b/src/valr_python/rest_client.py @@ -110,3 +110,26 @@ def _do(self, method: str, path: str, data: Optional[Dict] = None, params: Optio except JSONDecodeError as jde: raise RESTAPIException(res.status_code, f'valr-python: unknown API error. HTTP ({res.status_code}): {jde.msg}') + + + def _do_delete(self, method: str, path: str, data: Optional[Dict] = None, params: Optional[Dict] = None, + is_authenticated: bool = False, subaccount_id: str = '') -> Optional[Union[List, Dict]]: + """Executes API request and returns the response. + + Includes HTTP 429 handling by honouring VALR's 429 Retry-After header cool-down. + """ + headers = {} + if data: + data = json.dumps(data, cls=DecimalEncoder) # serialize decimals as str + headers["Content-Type"] = "application/json" + params_str = parse.urlencode(params, safe=":") if params else None + if is_authenticated: + # todo - fix data processing in valr headers + headers.update(_get_valr_headers(api_key=self.api_key, api_secret=self.api_secret, method=method, + path=f'{path}?{params_str}' if params_str else path, data=data, + subaccount_id=subaccount_id)) + url = self._base_url + '/' + path.lstrip('/') + args = dict(timeout=self._timeout, data=data, headers=headers) + if params_str: + args['params'] = params_str + return self._session.request(method, url, **args)