From 6b959ebf3b276964bdfc568e62faba8f7aeda1fa Mon Sep 17 00:00:00 2001 From: ThomasProctor Date: Wed, 28 Mar 2018 17:43:11 -0400 Subject: [PATCH 1/3] ResponseGroup=AlternateVersions support --- amazon/api.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/amazon/api.py b/amazon/api.py index 7df6483..bc098b2 100644 --- a/amazon/api.py +++ b/amazon/api.py @@ -1140,6 +1140,34 @@ def list_price(self): else: return None, None + @property + def alternate_versions(self): + """AlternateVersions. + + Returns a list of dicts of items. Used for a search or lookup + using the `ResponseGroup="AlternateVersions"` keyword argument. + + :return: + Returns a list of dicts with the keys 'asin', 'title', and + 'binding. + """ + + def version_dict(version): + asin = self._safe_get_element_text('ASIN', root=version) + title = self._safe_get_element_text('Title', root=version) + binding = self._safe_get_element_text('Binding', root=version) + return {'asin': asin, + 'title': title, + 'binding': binding} + + alternates_elm = self._safe_get_element('AlternateVersions') + if alternates_elm is not None: + versions = [version_dict(version) + for version in alternates_elm.getchildren()] + return versions + else: + return [] + def get_attribute(self, name): """Get Attribute From 7c1d2b0599540306ff10e55481140ef87c3d1737 Mon Sep 17 00:00:00 2001 From: ThomasProctor Date: Wed, 28 Mar 2018 18:53:34 -0400 Subject: [PATCH 2/3] ResponseGroup='AlternateVersions' test --- tests.py | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/tests.py b/tests.py index d8b7c69..b6ba435 100644 --- a/tests.py +++ b/tests.py @@ -481,6 +481,29 @@ def test_images(self): assert_equals(type(product.images), list) assert_equals(len(product.images), 7) + @flaky(max_runs=3, rerun_filter=delay_rerun) + def test_alternate_versions(self): + """Test alternate_versions property + + Test that the images property has a value when using the + AlternateVersions ResponseGroup. + + This test tries to be as perminant as possible. It doesn't + depend on any specific results that could be ruined if a new + version is added that ends up being the first one in the list, + instead only checking that an alternate version is returned + and that it has the right properties. + """ + product = self.amazon.lookup(ResponseGroup='AlternateVersions', + ItemId='1491914254') + assert_equals(type(product.alternate_versions), list) + assert_true(len(product.alternate_versions) > 0) + assert_equals(type(product.alternate_versions[0]), dict) + assert_equals(len(product.alternate_versions[0]), 3) + assert_true('asin' in product.alternate_versions[0].keys()) + assert_true('title' in product.alternate_versions[0].keys()) + assert_true('binding' in product.alternate_versions[0].keys()) + class TestAmazonCart(unittest.TestCase): def setUp(self): @@ -606,4 +629,4 @@ def test_cart_delete(self): assert_raises(KeyError, new_cart.__getitem__, cart_item_id) if __name__ == '__main__': - unittest.main() \ No newline at end of file + unittest.main() From dfeea0b39373fc9f9335cfc213c500db353f44ae Mon Sep 17 00:00:00 2001 From: ThomasProctor Date: Thu, 29 Mar 2018 11:32:29 -0400 Subject: [PATCH 3/3] raise error on invalid BrowseNodeId --- amazon/api.py | 2 +- tests.py | 11 +++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/amazon/api.py b/amazon/api.py index bc098b2..c0e1493 100644 --- a/amazon/api.py +++ b/amazon/api.py @@ -256,7 +256,7 @@ def browse_node_lookup(self, ResponseGroup="BrowseNodeInfo", **kwargs): response = self.api.BrowseNodeLookup( ResponseGroup=ResponseGroup, **kwargs) root = objectify.fromstring(response) - if root.BrowseNodes.Request.IsValid == 'False': + if hasattr(root.BrowseNodes.Request, 'Errors'): code = root.BrowseNodes.Request.Errors.Error.Code msg = root.BrowseNodes.Request.Errors.Error.Message raise BrowseNodeLookupException( diff --git a/tests.py b/tests.py index b6ba435..b5ec875 100644 --- a/tests.py +++ b/tests.py @@ -14,7 +14,8 @@ CartInfoMismatchException, SearchException, AmazonSearch, - AsinNotFound) + AsinNotFound, + BrowseNodeLookupException) _AMAZON_ACCESS_KEY = None _AMAZON_SECRET_KEY = None @@ -214,7 +215,6 @@ def test_search_iterate_pages(self): pass assert_true(products.is_last_page) - @flaky(max_runs=3, rerun_filter=delay_rerun) def test_search_no_results(self): """Test Product Search with no results. @@ -288,6 +288,10 @@ def test_browse_node_lookup(self): assert_equals(bn.id, bnid) assert_equals(bn.name, 'eBook Readers') assert_equals(bn.is_category_root, False) + invalid_bnid = 1036682 + assert_raises(BrowseNodeLookupException, + self.amazon.browse_node_lookup, + BrowseNodeId=invalid_bnid) @flaky(max_runs=3, rerun_filter=delay_rerun) def test_obscure_date(self): @@ -432,7 +436,7 @@ def test_studio(self): @flaky(max_runs=3, rerun_filter=delay_rerun) def test_is_preorder(self): product = self.amazon.lookup(ItemId="B01NBTSVDN") - assert_equals(product.is_preorder , None) + assert_equals(product.is_preorder, None) @flaky(max_runs=3, rerun_filter=delay_rerun) def test_detail_page_url(self): @@ -464,7 +468,6 @@ def test_availability_min_max_hours(self): assert_equals(product.availability_min_hours, '0') assert_equals(product.availability_max_hours, '0') - def test_kwargs(self): amazon = AmazonAPI(_AMAZON_ACCESS_KEY, _AMAZON_SECRET_KEY, _AMAZON_ASSOC_TAG, MaxQPS=0.7)