Skip to content

Commit c4e852b

Browse files
committed
Solved item limit, added request retry and improved exceptions
1 parent da578bc commit c4e852b

1 file changed

Lines changed: 85 additions & 70 deletions

File tree

amazon/paapi.py

Lines changed: 85 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
from paapi5_python_sdk.get_items_request import GetItemsRequest
1010
from paapi5_python_sdk.search_items_request import SearchItemsRequest
1111
from paapi5_python_sdk.get_variations_request import GetVariationsRequest
12-
from paapi5_python_sdk.get_browse_nodes_request import GetBrowseNodesRequest
1312
from paapi5_python_sdk.partner_type import PartnerType
13+
from paapi5_python_sdk.rest import ApiException
1414

1515
import time
1616

@@ -37,7 +37,7 @@ def __init__(self, key: str, secret: str, tag: str, country: str, throttling=0.9
3737
self.key = key
3838
self.secret = secret
3939
self.tag = tag
40-
if 1 <= throttling > 0:
40+
if 1 >= throttling > 0:
4141
self.throttling = throttling
4242
elif throttling <= 0:
4343
raise AmazonException('ValueError', 'Throttling should be greater than 0')
@@ -91,19 +91,25 @@ def get_products(self, product_ids: [str, list], condition='Any', async_req=Fals
9191
except Exception as exception:
9292
raise AmazonException(exception.status, exception.reason)
9393

94+
for x in range(3):
95+
try:
96+
# Wait before doing the request
97+
wait_time = 1 / self.throttling - (time.time() - self.last_query_time)
98+
if wait_time > 0:
99+
time.sleep(wait_time)
100+
self.last_query_time = time.time()
101+
102+
# Send the request and create results
103+
if async_req:
104+
thread = self.api.get_items(request, async_req=True)
105+
response = thread.get()
106+
else:
107+
response = self.api.get_items(request)
108+
break
109+
except ApiException as e:
110+
if x == 2:
111+
raise AmazonException('ApiException', e)
94112
try:
95-
# Wait before doing the request
96-
wait_time = 1 / self.throttling - (time.time() - self.last_query_time)
97-
if wait_time > 0:
98-
time.sleep(wait_time)
99-
self.last_query_time = time.time()
100-
101-
# Send the request and create results
102-
if async_req:
103-
thread = self.api.get_items(request, async_req=True)
104-
response = thread.get()
105-
else:
106-
response = self.api.get_items(request)
107113
if response.items_result is not None:
108114
if len(response.items_result.items) > 0:
109115
for item in response.items_result.items:
@@ -142,10 +148,10 @@ def get_product(self, product_id: str, condition='Any', async_req=False):
142148

143149
def search_products(self, item_count=10, item_page=1, items_per_page=10, actor=None,
144150
artist=None, author=None, availability=None, brand=None, browse_node=None,
145-
condition=None, currency=None, delivery=None, keywords=None, languages=None,
146-
max_price=None, min_price=None, min_rating=None, min_discount=None,
147-
merchant=None, search_index=None, sort_by=None, title=None,
148-
async_req=False):
151+
condition='Any', currency=None, delivery=None, keywords=None,
152+
languages=None, max_price=None, min_price=None, min_rating=None,
153+
min_discount=None, merchant=None, search_index=None, sort_by=None,
154+
title=None, async_req=False):
149155
"""Search products on Amazon using different parameters. At least one of the
150156
following parameters should be used: keywords, actor, artist, author, brand,
151157
title.
@@ -214,17 +220,8 @@ def search_products(self, item_count=10, item_page=1, items_per_page=10, actor=N
214220
'provided: keywords, actor, artist, author, brand,'
215221
'title')
216222

217-
# Remove 10 items limit from Amazon API
218-
last_page_list = [False for x in range(int(item_count / items_per_page))]
219-
if last_page_list:
220-
last_page_list.pop()
221-
last_page_list.append(True)
222-
last_page_items = item_count % items_per_page
223-
224223
results = []
225-
for last_page in last_page_list:
226-
if last_page and len(last_page_list) > 1:
227-
items_per_page = last_page_items
224+
while len(results) < item_count:
228225
try:
229226
request = SearchItemsRequest(
230227
partner_tag=self.tag,
@@ -252,28 +249,41 @@ def search_products(self, item_count=10, item_page=1, items_per_page=10, actor=N
252249
search_index=search_index,
253250
sort_by=sort_by,
254251
title=title)
255-
except Exception as exception:
256-
raise AmazonException(exception.status, exception.reason)
257-
252+
except KeyError:
253+
raise AmazonException('KeyError', 'Invalid condition value')
254+
except ValueError as e:
255+
raise AmazonException('ValueError', e)
256+
except Exception as e:
257+
raise AmazonException('Error', e)
258+
259+
for x in range(3):
260+
try:
261+
# Wait before doing the request
262+
wait_time = 1 / self.throttling - (time.time() - self.last_query_time)
263+
if wait_time > 0:
264+
time.sleep(wait_time)
265+
self.last_query_time = time.time()
266+
267+
# Send the request and create results
268+
if async_req:
269+
thread = self.api.search_items(request, async_req=True)
270+
response = thread.get()
271+
else:
272+
response = self.api.search_items(request)
273+
break
274+
except ApiException as e:
275+
if x == 2:
276+
raise AmazonException('ApiException', e)
258277
try:
259-
# Wait before doing the request
260-
wait_time = 1 / self.throttling - (time.time() - self.last_query_time)
261-
if wait_time > 0:
262-
time.sleep(wait_time)
263-
self.last_query_time = time.time()
264-
265-
# Send the request and create results
266-
if async_req:
267-
thread = self.api.search_items(request, async_req=True)
268-
response = thread.get()
269-
else:
270-
response = self.api.search_items(request)
271278
if response.search_result is not None:
272279
for item in response.search_result.items:
273280
results.append(parse_product(item))
281+
if len(results) >= item_count:
282+
break
283+
else:
284+
break
274285
if response.errors is not None:
275286
raise AmazonException(response.errors[0].code, response.errors[0].message)
276-
277287
except Exception as exception:
278288
raise AmazonException(exception.reason, exception.body)
279289
item_page += 1
@@ -285,7 +295,7 @@ def search_products(self, item_count=10, item_page=1, items_per_page=10, actor=N
285295
else:
286296
return None
287297

288-
def get_variations(self, asin, item_count=10, item_page=1, items_per_page=10, condition=None,
298+
def get_variations(self, asin, item_count=10, item_page=1, items_per_page=10, condition='Any',
289299
currency=None, languages=None, merchant=None, async_req=False):
290300

291301
if items_per_page > 10 or items_per_page < 1:
@@ -295,17 +305,8 @@ def get_variations(self, asin, item_count=10, item_page=1, items_per_page=10, co
295305
if item_page > 10 or item_page < 1:
296306
raise AmazonException('ValueError', 'Arg item_page should be between 1 and 10')
297307

298-
# Remove 10 items limit from Amazon API
299-
last_page_list = [False for x in range(int(item_count / items_per_page))]
300-
if last_page_list:
301-
last_page_list.pop()
302-
last_page_list.append(True)
303-
last_page_items = item_count % items_per_page
304-
305308
results = []
306-
for last_page in last_page_list:
307-
if last_page and len(last_page_list) > 1:
308-
items_per_page = last_page_items
309+
while len(results) < item_count:
309310
try:
310311
request = GetVariationsRequest(
311312
partner_tag=self.tag,
@@ -320,25 +321,39 @@ def get_variations(self, asin, item_count=10, item_page=1, items_per_page=10, co
320321
variation_count=items_per_page,
321322
variation_page=item_page,
322323
resources=VARIATION_RESOURCES)
323-
except Exception as exception:
324-
raise AmazonException(exception.status, exception.reason)
325-
324+
except KeyError:
325+
raise AmazonException('KeyError', 'Invalid condition value')
326+
except ValueError as e:
327+
raise AmazonException('ValueError', e)
328+
except Exception as e:
329+
raise AmazonException('Error', e)
330+
331+
for x in range(3):
332+
try:
333+
# Wait before doing the request
334+
wait_time = 1 / self.throttling - (time.time() - self.last_query_time)
335+
if wait_time > 0:
336+
time.sleep(wait_time)
337+
self.last_query_time = time.time()
338+
339+
# Send the request and create results
340+
if async_req:
341+
thread = self.api.get_variations(request, async_req=True)
342+
response = thread.get()
343+
else:
344+
response = self.api.get_variations(request)
345+
break
346+
except ApiException as e:
347+
if x == 2:
348+
raise AmazonException('ApiException', e)
326349
try:
327-
# Wait before doing the request
328-
wait_time = 1 / self.throttling - (time.time() - self.last_query_time)
329-
if wait_time > 0:
330-
time.sleep(wait_time)
331-
self.last_query_time = time.time()
332-
333-
# Send the request and create results
334-
if async_req:
335-
thread = self.api.get_variations(request, async_req=True)
336-
response = thread.get()
337-
else:
338-
response = self.api.get_variations(request)
339350
if response.variations_result is not None:
340351
for item in response.variations_result.items:
341352
results.append(parse_product(item))
353+
if len(results) >= item_count:
354+
break
355+
else:
356+
break
342357
if response.errors is not None:
343358
raise AmazonException(response.errors[0].code, response.errors[0].message)
344359

0 commit comments

Comments
 (0)