diff --git a/amazon_paapi/api.py b/amazon_paapi/api.py index 8a7f3ca..57f80f7 100644 --- a/amazon_paapi/api.py +++ b/amazon_paapi/api.py @@ -3,6 +3,9 @@ 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 @@ -10,9 +13,7 @@ from .helpers import arguments from .helpers import requests from .helpers.generators import get_list_chunks - -from typing import List, Union -import time +from .helpers.items import sort_items class AmazonApi: @@ -42,19 +43,22 @@ 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]: + include_unavailable: bool = False, + **kwargs + ) -> List[models.Item]: """Get items information from Amazon. @@ -69,6 +73,8 @@ def get_items(self, 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: @@ -86,21 +92,22 @@ 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 = [] - 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) - return results + return sort_items(results, items_ids, include_unavailable) - def search_items(self, + def search_items( + self, item_count: int = None, item_page: int = None, actor: str = None, @@ -122,7 +129,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 +213,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 +222,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 +270,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: diff --git a/amazon_paapi/helpers/arguments.py b/amazon_paapi/helpers/arguments.py index 0c4bf3d..8b7034e 100644 --- a/amazon_paapi/helpers/arguments.py +++ b/amazon_paapi/helpers/arguments.py @@ -19,8 +19,8 @@ def get_items_ids(items: Union[str, List[str]]) -> List[str]: if items_ids: return items_ids - else: - raise AsinNotFoundException('No ASIN codes have been found.') + + raise AsinNotFoundException('No ASIN codes have been found.') def check_search_args(**kwargs): diff --git a/amazon_paapi/helpers/items.py b/amazon_paapi/helpers/items.py new file mode 100644 index 0000000..499faaf --- /dev/null +++ b/amazon_paapi/helpers/items.py @@ -0,0 +1,17 @@ +"""Module to manage items""" + +from typing import List +from .. import models + + +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 diff --git a/amazon_paapi/tools/asin.py b/amazon_paapi/tools/asin.py index 436aafc..e531977 100644 --- a/amazon_paapi/tools/asin.py +++ b/amazon_paapi/tools/asin.py @@ -1,18 +1,18 @@ """Some useful tools.""" -from ..errors import AsinNotFoundException import re +from ..errors import AsinNotFoundException 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) - else: - raise AsinNotFoundException('Asin not found: ' + text) + return asin.group(2).upper() + + raise AsinNotFoundException('Asin not found: ' + text) 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',