From b72d6e80f68458db2839da508d93f09975b72239 Mon Sep 17 00:00:00 2001 From: Scandie Date: Tue, 5 Sep 2017 15:12:57 +0300 Subject: [PATCH 1/3] Add retry decorators Add retry decorator to methods '_get_resource_item' and '_patch_resource_item', which will be trying to repeat request several times in case RequestFailed exception was raised --- openprocurement_client/clients.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/openprocurement_client/clients.py b/openprocurement_client/clients.py index a84788b..ab4e877 100755 --- a/openprocurement_client/clients.py +++ b/openprocurement_client/clients.py @@ -9,6 +9,7 @@ from retrying import retry from munch import munchify +from .exceptions import RequestFailed from openprocurement_client.resources.document_service import \ DocumentServiceClient @@ -77,6 +78,10 @@ def _delete_resource_item(self, url, headers=None): return munchify(loads(response_item.text)) raise InvalidResponse(response_item) + @retry(wait_exponential_multiplier=200, + wait_exponential_max=1200, + stop_max_delay=45000, + retry_on_exception=lambda exc: isinstance(exc, RequestFailed)) def _get_resource_item(self, url, headers=None): _headers = self.headers.copy() _headers.update(headers or {}) @@ -102,6 +107,10 @@ def _get_resource_items(self, params=None, feed='changes'): raise InvalidResponse(response) + @retry(wait_exponential_multiplier=200, + wait_exponential_max=1200, + stop_max_delay=45000, + retry_on_exception=lambda exc: isinstance(exc, RequestFailed)) def _patch_resource_item(self, url, payload, headers=None): _headers = self.headers.copy() _headers.update(headers or {}) From 1ad1ed2d810e241bd8fa8c99204c398388e0e022 Mon Sep 17 00:00:00 2001 From: Scandie Date: Thu, 7 Sep 2017 15:05:01 +0300 Subject: [PATCH 2/3] Move retry decorators from APIBaseClient to LotsClient and AssetsClient --- openprocurement_client/clients.py | 9 --------- openprocurement_client/resources/assets.py | 19 +++++++++++++++++-- openprocurement_client/resources/lots.py | 19 +++++++++++++++++-- 3 files changed, 34 insertions(+), 13 deletions(-) diff --git a/openprocurement_client/clients.py b/openprocurement_client/clients.py index ab4e877..a84788b 100755 --- a/openprocurement_client/clients.py +++ b/openprocurement_client/clients.py @@ -9,7 +9,6 @@ from retrying import retry from munch import munchify -from .exceptions import RequestFailed from openprocurement_client.resources.document_service import \ DocumentServiceClient @@ -78,10 +77,6 @@ def _delete_resource_item(self, url, headers=None): return munchify(loads(response_item.text)) raise InvalidResponse(response_item) - @retry(wait_exponential_multiplier=200, - wait_exponential_max=1200, - stop_max_delay=45000, - retry_on_exception=lambda exc: isinstance(exc, RequestFailed)) def _get_resource_item(self, url, headers=None): _headers = self.headers.copy() _headers.update(headers or {}) @@ -107,10 +102,6 @@ def _get_resource_items(self, params=None, feed='changes'): raise InvalidResponse(response) - @retry(wait_exponential_multiplier=200, - wait_exponential_max=1200, - stop_max_delay=45000, - retry_on_exception=lambda exc: isinstance(exc, RequestFailed)) def _patch_resource_item(self, url, payload, headers=None): _headers = self.headers.copy() _headers.update(headers or {}) diff --git a/openprocurement_client/resources/assets.py b/openprocurement_client/resources/assets.py index fce60b0..89f8820 100644 --- a/openprocurement_client/resources/assets.py +++ b/openprocurement_client/resources/assets.py @@ -1,6 +1,9 @@ # -*- coding: utf-8 -*- +from retrying import retry + from openprocurement_client.clients import APIResourceClient from openprocurement_client.constants import ASSETS +from openprocurement_client.exceptions import RequestFailed class AssetsClient(APIResourceClient): @@ -12,6 +15,18 @@ def __init__(self, *args, **kwargs): super(AssetsClient, self).__init__(resource=self.resource, *args, **kwargs) - get_asset = APIResourceClient.get_resource_item - get_assets = APIResourceClient.get_resource_items + + @retry(wait_exponential_multiplier=200, + wait_exponential_max=1200, + stop_max_delay=45000, + retry_on_exception=lambda exc: isinstance(exc, RequestFailed)) + def patch_asset(self, asset_id, patch_data): + return self.patch_resource_item(asset_id, patch_data) + + @retry(wait_exponential_multiplier=200, + wait_exponential_max=1200, + stop_max_delay=45000, + retry_on_exception=lambda exc: isinstance(exc, RequestFailed)) + def get_asset(self, asset_id): + return self.get_resource_item(asset_id) diff --git a/openprocurement_client/resources/lots.py b/openprocurement_client/resources/lots.py index 62b57b4..a465aa7 100644 --- a/openprocurement_client/resources/lots.py +++ b/openprocurement_client/resources/lots.py @@ -1,6 +1,9 @@ # -*- coding: utf-8 -*- +from retrying import retry + from openprocurement_client.clients import APIResourceClient from openprocurement_client.constants import LOTS +from openprocurement_client.exceptions import RequestFailed class LotsClient(APIResourceClient): @@ -12,6 +15,18 @@ def __init__(self, *args, **kwargs): super(LotsClient, self).__init__(resource=self.resource, *args, **kwargs) - get_lot = APIResourceClient.get_resource_item - get_lots = APIResourceClient.get_resource_items + + @retry(wait_exponential_multiplier=200, + wait_exponential_max=1200, + stop_max_delay=45000, + retry_on_exception=lambda exc: isinstance(exc, RequestFailed)) + def patch_lot(self, lot_id, patch_data): + return self.patch_resource_item(lot_id, patch_data) + + @retry(wait_exponential_multiplier=200, + wait_exponential_max=1200, + stop_max_delay=45000, + retry_on_exception=lambda exc: isinstance(exc, RequestFailed)) + def get_lot(self, lot_id): + return self.get_resource_item(lot_id) From 1ac0e70010799fb3ee89ef803c2427dff2a67e93 Mon Sep 17 00:00:00 2001 From: Scandie Date: Fri, 8 Sep 2017 11:17:46 +0300 Subject: [PATCH 3/3] Update tests for new methods --- .../tests/test_registry_client.py | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/openprocurement_client/tests/test_registry_client.py b/openprocurement_client/tests/test_registry_client.py index 5579718..abeb4ec 100644 --- a/openprocurement_client/tests/test_registry_client.py +++ b/openprocurement_client/tests/test_registry_client.py @@ -96,7 +96,7 @@ def test_get_asset(self): asset = self.client.get_asset(TEST_ASSET_KEYS.asset_id) self.assertEqual(asset, self.asset) - def test_patch_asset(self): + def test_patch_resource_item(self): setup_routing(self.app, routes=["asset_patch"]) asset_id = self.asset.data.id patch_data = {'data': {'description': 'test_patch_asset'}} @@ -106,6 +106,16 @@ def test_patch_asset(self): self.assertEqual(patched_asset.data.description, patch_data['data']['description']) + def test_patch_asset(self): + setup_routing(self.app, routes=["asset_patch"]) + asset_id = self.asset.data.id + patch_data = {'data': {'description': 'test_patch_asset'}} + patched_asset = self.client.patch_asset(asset_id, + patch_data) + self.assertEqual(patched_asset.data.id, self.asset.data.id) + self.assertEqual(patched_asset.data.description, + patch_data['data']['description']) + class LotsRegistryTestCase(BaseTestClass): def setUp(self): @@ -136,7 +146,7 @@ def test_get_lot(self): lot = self.client.get_lot(TEST_LOT_KEYS.lot_id) self.assertEqual(lot, self.lot) - def test_patch_lot(self): + def test_patch_resource_item(self): setup_routing(self.app, routes=["lot_patch"]) lot_id = self.lot.data.id patch_data = {'data': {'description': 'test_patch_lot'}} @@ -145,6 +155,15 @@ def test_patch_lot(self): self.assertEqual(patched_lot.data.description, patch_data['data']['description']) + def test_patch_lot(self): + setup_routing(self.app, routes=["lot_patch"]) + lot_id = self.lot.data.id + patch_data = {'data': {'description': 'test_patch_lot'}} + patched_lot = self.client.patch_lot(lot_id, patch_data) + self.assertEqual(patched_lot.data.id, lot_id) + self.assertEqual(patched_lot.data.description, + patch_data['data']['description']) + def suite(): suite = unittest.TestSuite()