From 76067371f7c7f10331d40b50b2ac3e6a1fad3317 Mon Sep 17 00:00:00 2001 From: Sergio Abad Date: Wed, 17 Nov 2021 19:50:36 +0100 Subject: [PATCH 1/7] Refactored get_asin --- amazon_paapi/tools/asin.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/amazon_paapi/tools/asin.py b/amazon_paapi/tools/asin.py index 436aafc..70cef30 100644 --- a/amazon_paapi/tools/asin.py +++ b/amazon_paapi/tools/asin.py @@ -1,7 +1,7 @@ """Some useful tools.""" -from ..errors import AsinNotFoundException import re +from ..errors import AsinNotFoundException def get_asin(text: str) -> str: @@ -14,5 +14,5 @@ def get_asin(text: str) -> str: asin = re.search(r'(dp|gp/product|gp/aw/d|dp/product)/([a-zA-Z0-9]{10})', text) if asin: return asin.group(2) - else: - raise AsinNotFoundException('Asin not found: ' + text) + + raise AsinNotFoundException('Asin not found: ' + text) From 11924fcb7683cdd2d58792f56cc4b443553cc401 Mon Sep 17 00:00:00 2001 From: Sergio Abad Date: Wed, 17 Nov 2021 20:11:32 +0100 Subject: [PATCH 2/7] Updated api module for linters --- amazon_paapi/api.py | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/amazon_paapi/api.py b/amazon_paapi/api.py index 8a7f3ca..28861ce 100644 --- a/amazon_paapi/api.py +++ b/amazon_paapi/api.py @@ -3,6 +3,8 @@ A simple Python wrapper for the last version of the Amazon Product Advertising API. """ +from typing import List, Union +import time from . import models from .sdk.api.default_api import DefaultApi @@ -11,9 +13,6 @@ from .helpers import requests from .helpers.generators import get_list_chunks -from typing import List, Union -import time - class AmazonApi: """Provides methods to get information from Amazon using your API credentials. @@ -42,19 +41,21 @@ def __init__(self, key: str, secret: str, tag: str, country: models.Country, thr self._host = 'webservices.amazon.' + models.regions.DOMAINS[country] self._region = models.regions.REGIONS[country] self._marketplace = 'www.amazon.' + models.regions.DOMAINS[country] - except KeyError: - raise InvalidArgumentException('Country code is not correct') + except KeyError as error: + raise InvalidArgumentException('Country code is not correct') from error self._api = DefaultApi(key, secret, self._host, self._region) - def get_items(self, + def get_items( + self, items: Union[str, List[str]], condition: models.Condition = None, merchant: models.Merchant = None, currency_of_preference: str = None, languages_of_preference: List[str] = None, - **kwargs) -> List[models.Item]: + **kwargs + ) -> List[models.Item]: """Get items information from Amazon. @@ -86,7 +87,7 @@ def get_items(self, 'merchant': merchant, 'currency_of_preference': currency_of_preference, 'languages_of_preference': languages_of_preference - }) + }) items_ids = arguments.get_items_ids(items) results = [] @@ -100,7 +101,8 @@ def get_items(self, return results - def search_items(self, + def search_items( + self, item_count: int = None, item_page: int = None, actor: str = None, @@ -122,7 +124,8 @@ def search_items(self, min_reviews_rating: int = None, search_index: str = None, sort_by: models.SortBy = None, - **kwargs) -> models.SearchResult: + **kwargs + ) -> models.SearchResult: """Searches for items on Amazon based on a search query. At least one of the following parameters should be specified: ``keywords``, ``actor``, ``artist``, ``author``, ``brand`` or ``title``. @@ -205,7 +208,8 @@ def search_items(self, return requests.get_search_items_response(self, request) - def get_variations(self, + def get_variations( + self, asin: str, variation_count: int = None, variation_page: int = None, @@ -213,7 +217,8 @@ def get_variations(self, currency_of_preference: str = None, languages_of_preference: List[str] = None, merchant: models.Merchant = None, - **kwargs) -> models.VariationsResult: + **kwargs + ) -> models.VariationsResult: """Returns a set of items that are the same product, but differ according to a consistent theme, for example size and color. A variation is a child ASIN. @@ -260,10 +265,12 @@ def get_variations(self, return requests.get_variations_response(self, request) - def get_browse_nodes(self, + def get_browse_nodes( + self, browse_node_ids: List[str], languages_of_preference: List[str] = None, - **kwargs) -> List[models.BrowseNode]: + **kwargs + ) -> List[models.BrowseNode]: """Returns the specified browse node's information like name, children and ancestors. Args: From 5f09939d0ce7e87cfbaeb31c8d5347610b72ca33 Mon Sep 17 00:00:00 2001 From: Sergio Abad Date: Wed, 17 Nov 2021 20:41:02 +0100 Subject: [PATCH 3/7] Added include_unavailable for get_items --- amazon_paapi/api.py | 8 ++++++++ amazon_paapi/helpers/items.py | 11 +++++++++++ 2 files changed, 19 insertions(+) create mode 100644 amazon_paapi/helpers/items.py diff --git a/amazon_paapi/api.py b/amazon_paapi/api.py index 28861ce..b22f846 100644 --- a/amazon_paapi/api.py +++ b/amazon_paapi/api.py @@ -6,12 +6,14 @@ from typing import List, Union import time + from . import models from .sdk.api.default_api import DefaultApi from .errors import InvalidArgumentException from .helpers import arguments from .helpers import requests from .helpers.generators import get_list_chunks +from .helpers.items import get_items_including_unavailable class AmazonApi: @@ -54,6 +56,7 @@ def get_items( merchant: models.Merchant = None, currency_of_preference: str = None, languages_of_preference: List[str] = None, + include_unavailable: bool = False, **kwargs ) -> List[models.Item]: @@ -70,6 +73,8 @@ def get_items( information should be returned. Expected currency code format is ISO 4217. languages_of_preference (``list[str]``, optional): Languages in order of preference in which the item information should be returned. + include_unavailable (``bool``, optional): The returned list includes not available + items. Not available items have the ASIN and item_info equals None. Defaults to False. kwargs (``dict``, optional): Any other arguments to be passed to the Amazon API. Returns: @@ -98,6 +103,9 @@ def get_items( items_response = requests.get_items_response(self, request) results.extend(items_response) + if include_unavailable: + results = get_items_including_unavailable(results, items_ids) + return results diff --git a/amazon_paapi/helpers/items.py b/amazon_paapi/helpers/items.py new file mode 100644 index 0000000..9902e49 --- /dev/null +++ b/amazon_paapi/helpers/items.py @@ -0,0 +1,11 @@ +"""Module to manage items""" + +from typing import List +from .. import models + + +def get_items_including_unavailable(items: List[models.Item], items_ids: List[str]) -> List[models.Item]: + for index, asin in enumerate(items_ids): + if items[index].asin != asin: + items.insert(index, models.Item(asin=asin)) + return items From 5bb3b50dcfab8cd59acbd38851399590c7b82737 Mon Sep 17 00:00:00 2001 From: Sergio Abad Date: Wed, 17 Nov 2021 20:58:53 +0100 Subject: [PATCH 4/7] Remove repeated item_ids --- amazon_paapi/helpers/arguments.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/amazon_paapi/helpers/arguments.py b/amazon_paapi/helpers/arguments.py index 0c4bf3d..23ac578 100644 --- a/amazon_paapi/helpers/arguments.py +++ b/amazon_paapi/helpers/arguments.py @@ -18,9 +18,9 @@ def get_items_ids(items: Union[str, List[str]]) -> List[str]: items_ids = [get_asin(x.strip()) for x in items] if items_ids: - return items_ids - else: - raise AsinNotFoundException('No ASIN codes have been found.') + return list(set(items_ids)) + + raise AsinNotFoundException('No ASIN codes have been found.') def check_search_args(**kwargs): From 6f955a932b8ec23667724e05679167a1e2e4ff83 Mon Sep 17 00:00:00 2001 From: Sergio Abad Date: Wed, 17 Nov 2021 22:29:20 +0100 Subject: [PATCH 5/7] Items are correctly sorted and avoid duplicated API calls --- amazon_paapi/api.py | 9 +++------ amazon_paapi/helpers/arguments.py | 2 +- amazon_paapi/helpers/items.py | 16 +++++++++++----- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/amazon_paapi/api.py b/amazon_paapi/api.py index b22f846..57f80f7 100644 --- a/amazon_paapi/api.py +++ b/amazon_paapi/api.py @@ -13,7 +13,7 @@ from .helpers import arguments from .helpers import requests from .helpers.generators import get_list_chunks -from .helpers.items import get_items_including_unavailable +from .helpers.items import sort_items class AmazonApi: @@ -97,16 +97,13 @@ def get_items( items_ids = arguments.get_items_ids(items) results = [] - for asin_chunk in get_list_chunks(items_ids, chunk_size=10): + for asin_chunk in get_list_chunks(list(set(items_ids)), chunk_size=10): request = requests.get_items_request(self, asin_chunk, **kwargs) self._throttle() items_response = requests.get_items_response(self, request) results.extend(items_response) - if include_unavailable: - results = get_items_including_unavailable(results, items_ids) - - return results + return sort_items(results, items_ids, include_unavailable) def search_items( diff --git a/amazon_paapi/helpers/arguments.py b/amazon_paapi/helpers/arguments.py index 23ac578..8b7034e 100644 --- a/amazon_paapi/helpers/arguments.py +++ b/amazon_paapi/helpers/arguments.py @@ -18,7 +18,7 @@ def get_items_ids(items: Union[str, List[str]]) -> List[str]: items_ids = [get_asin(x.strip()) for x in items] if items_ids: - return list(set(items_ids)) + return items_ids raise AsinNotFoundException('No ASIN codes have been found.') diff --git a/amazon_paapi/helpers/items.py b/amazon_paapi/helpers/items.py index 9902e49..499faaf 100644 --- a/amazon_paapi/helpers/items.py +++ b/amazon_paapi/helpers/items.py @@ -4,8 +4,14 @@ from .. import models -def get_items_including_unavailable(items: List[models.Item], items_ids: List[str]) -> List[models.Item]: - for index, asin in enumerate(items_ids): - if items[index].asin != asin: - items.insert(index, models.Item(asin=asin)) - return items +def sort_items(items: List[models.Item], items_ids: List[str], include_unavailable: bool) -> List[models.Item]: + sorted_items = [] + + for asin in items_ids: + matches = list(filter(lambda item, asin=asin: item.asin == asin, items)) + if matches: + sorted_items.append(matches[0]) + elif include_unavailable: + sorted_items.append(models.Item(asin=asin)) + + return sorted_items From a03803294e0227931b49a2359970a33c385dcfdd Mon Sep 17 00:00:00 2001 From: Sergio Abad Date: Wed, 17 Nov 2021 22:54:11 +0100 Subject: [PATCH 6/7] Automatically convert ASIN to uppercase --- amazon_paapi/tools/asin.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/amazon_paapi/tools/asin.py b/amazon_paapi/tools/asin.py index 70cef30..e531977 100644 --- a/amazon_paapi/tools/asin.py +++ b/amazon_paapi/tools/asin.py @@ -7,12 +7,12 @@ def get_asin(text: str) -> str: """Returns the ASIN from a given text. Raises AsinNotFoundException on fail.""" # Return if text is an ASIN - if re.search(r'^[A-Z0-9]{10}$', text): - return text + if re.search(r'^[a-zA-Z0-9]{10}$', text): + return text.upper() # Extract ASIN from URL searching for alphanumeric and 10 digits asin = re.search(r'(dp|gp/product|gp/aw/d|dp/product)/([a-zA-Z0-9]{10})', text) if asin: - return asin.group(2) + return asin.group(2).upper() raise AsinNotFoundException('Asin not found: ' + text) From 2ae997a2dd9e321e8c53caebe1d16aa2ba1f2803 Mon Sep 17 00:00:00 2001 From: Sergio Abad Date: Wed, 17 Nov 2021 22:54:23 +0100 Subject: [PATCH 7/7] Updated version number --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index bb7b9e3..2102a7c 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ setuptools.setup( name='python-amazon-paapi', - version='4.1.1', + version='4.2.0', author='Sergio Abad', author_email='sergio.abad@bytelix.com', description='Amazon Product Advertising API 5.0 wrapper for Python',