Skip to content

Commit c829efa

Browse files
authored
Merge pull request #19 from sergioteula/dev-throttling-improvement
Throttling and SDK updates
2 parents 33e2227 + e14cd58 commit c829efa

98 files changed

Lines changed: 18133 additions & 45 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Amazon Product Advertising API 5.0 wrapper for Python
22
=======================================================
3-
A simple Python wrapper for the [last version of the Amazon Product Advertising API](https://pypi.org/project/amightygirl.paapi5-python-sdk/). This module allows to get product information from Amazon using the official API in an easier way.
3+
A simple Python wrapper for the [last version of the Amazon Product Advertising API](https://webservices.amazon.com/paapi5/documentation/quick-start/using-sdk.html). This module allows to get product information from Amazon using the official API in an easier way.
44

55
[![PyPI](https://img.shields.io/pypi/v/python-amazon-paapi?color=%231182C2&label=PyPI)](https://pypi.org/project/python-amazon-paapi/)
66
[![Python](https://img.shields.io/badge/Python-2.x%20%7C%203.x-%23FFD140)](https://www.python.org/)
@@ -65,12 +65,18 @@ Usage guide
6565

6666
**Throttling:**
6767

68-
Throttling value must be `0 < value <= 1`. This value throttles requests to a maximum of one request per `1 / value` seconds. Note that this value is a per-worker throttling, so applications with multiple workers may make more requests per second. Throttling value is [set by default](https://github.com/sergioteula/python-amazon-paapi/blob/master/amazon/paapi.py#L36) to `0.8` or one request per 1.25 seconds.
68+
Throttling value must be `greater than 0` or `False` to disable it. This value throttles requests to a maximum of one request every `1 / value` seconds. Note that this value is a per-worker throttling, so applications with multiple workers may make more requests per second. Throttling value is [set by default](https://github.com/sergioteula/python-amazon-paapi/blob/master/amazon/paapi.py#L36) to `0.8` or one request every 1.25 seconds.
6969

7070
amazon = AmazonAPI(KEY, SECRET, TAG, COUNTRY, throttling=0.5) # Max one request every two seconds
71+
amazon = AmazonAPI(KEY, SECRET, TAG, COUNTRY, throttling=False) # Unlimited requests per second
7172

7273
Changelog
7374
-------------
75+
Version 3.1.0
76+
- Added paapi5-python-sdk and removed amightygirl.paapi5-python-sdk.
77+
- Improved throttling and now possible to disable it.
78+
- Updated documentation.
79+
7480
Version 3.0.2
7581
- Changed to MIT License.
7682

amazon/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
"""Amazon Product Advertising API wrapper for Python"""
22

3-
__version__ = '3.0.2'
3+
__version__ = '3.1.0'
44
__author__ = 'Sergio Abad'

amazon/paapi.py

Lines changed: 39 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,13 @@
1212
from paapi5_python_sdk.partner_type import PartnerType
1313
from paapi5_python_sdk.rest import ApiException
1414

15-
import time
15+
from amazon.constant import DOMAINS, REGIONS, CONDITION
16+
from amazon.constant import PRODUCT_RESOURCES, SEARCH_RESOURCES, VARIATION_RESOURCES
17+
from amazon.exception import AmazonException
18+
from amazon.parse import parse_product
19+
from amazon.tools import get_asin, chunks
1620

17-
from .constant import DOMAINS, REGIONS, CONDITION
18-
from .constant import PRODUCT_RESOURCES, SEARCH_RESOURCES, VARIATION_RESOURCES
19-
from .exception import AmazonException
20-
from .parse import parse_product
21-
from .tools import get_asin, chunks
21+
import time
2222

2323

2424
class AmazonAPI:
@@ -30,19 +30,24 @@ class AmazonAPI:
3030
tag (str): The tag you want to use for the URL.
3131
country (str): Country code. Use one of the following:
3232
AU, BR, CA, FR, DE, IN, IT, JP, MX, ES, TR, AE, UK, US.
33-
throttling (float, optional): Reduce this value to wait longer
34-
between API calls.
33+
throttling (float, optional): It should be greater than 0 or False to disable throttling.
34+
This value determines wait time between API calls.
3535
"""
3636
def __init__(self, key: str, secret: str, tag: str, country: str, throttling=0.8):
3737
self.key = key
3838
self.secret = secret
3939
self.tag = tag
40-
if 1 >= throttling > 0:
41-
self.throttling = throttling
42-
elif throttling <= 0:
43-
raise AmazonException('ValueError', 'Throttling should be greater than 0')
44-
elif throttling > 1:
45-
raise AmazonException('ValueError', 'Throttling should be 1 or less')
40+
try:
41+
if throttling is True:
42+
raise ValueError
43+
elif throttling is False:
44+
self.throttling = False
45+
else:
46+
self.throttling = float(throttling)
47+
if self.throttling <= 0:
48+
raise ValueError
49+
except ValueError:
50+
raise AmazonException('ValueError', 'Throttling should be False or greater than 0')
4651
self.country = country
4752
try:
4853
self.host = 'webservices.amazon.' + DOMAINS[country]
@@ -54,6 +59,13 @@ def __init__(self, key: str, secret: str, tag: str, country: str, throttling=0.8
5459
self.api = DefaultApi(access_key=self.key, secret_key=self.secret, host=self.host,
5560
region=self.region)
5661

62+
def _throttle(self):
63+
if self.throttling:
64+
wait_time = 1 / self.throttling - (time.time() - self.last_query_time)
65+
if wait_time > 0:
66+
time.sleep(wait_time)
67+
self.last_query_time = time.time()
68+
5769
def get_products(self, product_ids: [str, list], condition='Any', merchant='All',
5870
async_req=False):
5971
"""Find product information for multiple products on Amazon.
@@ -100,13 +112,8 @@ def get_products(self, product_ids: [str, list], condition='Any', merchant='All'
100112

101113
for x in range(3):
102114
try:
103-
# Wait before doing the request
104-
wait_time = 1 / self.throttling - (time.time() - self.last_query_time)
105-
if wait_time > 0:
106-
time.sleep(wait_time)
107-
self.last_query_time = time.time()
108-
109115
# Send the request and create results
116+
self._throttle()
110117
if async_req:
111118
thread = self.api.get_items(request, async_req=True)
112119
response = thread.get()
@@ -259,13 +266,8 @@ def search_products(self, item_count=10, item_page=1, items_per_page=10, keyword
259266

260267
for x in range(3):
261268
try:
262-
# Wait before doing the request
263-
wait_time = 1 / self.throttling - (time.time() - self.last_query_time)
264-
if wait_time > 0:
265-
time.sleep(wait_time)
266-
self.last_query_time = time.time()
267-
268269
# Send the request and create results
270+
self._throttle()
269271
if async_req:
270272
thread = self.api.search_items(request, async_req=True)
271273
response = thread.get()
@@ -277,10 +279,11 @@ def search_products(self, item_count=10, item_page=1, items_per_page=10, keyword
277279
raise AmazonException('ApiException', e)
278280
try:
279281
if response.search_result is not None:
280-
for item in response.search_result.items:
281-
results.append(parse_product(item))
282-
if len(results) >= item_count:
283-
break
282+
if response.search_result.items is not None:
283+
for item in response.search_result.items:
284+
results.append(parse_product(item))
285+
if len(results) >= item_count:
286+
break
284287
else:
285288
break
286289
if response.errors is not None:
@@ -350,13 +353,8 @@ def get_variations(self, asin, item_count=10, item_page=1, items_per_page=10, co
350353

351354
for x in range(3):
352355
try:
353-
# Wait before doing the request
354-
wait_time = 1 / self.throttling - (time.time() - self.last_query_time)
355-
if wait_time > 0:
356-
time.sleep(wait_time)
357-
self.last_query_time = time.time()
358-
359356
# Send the request and create results
357+
self._throttle()
360358
if async_req:
361359
thread = self.api.get_variations(request, async_req=True)
362360
response = thread.get()
@@ -368,10 +366,11 @@ def get_variations(self, asin, item_count=10, item_page=1, items_per_page=10, co
368366
raise AmazonException('ApiException', e)
369367
try:
370368
if response.variations_result is not None:
371-
for item in response.variations_result.items:
372-
results.append(parse_product(item))
373-
if len(results) >= item_count:
374-
break
369+
if response.variations_result.items is not None:
370+
for item in response.variations_result.items:
371+
results.append(parse_product(item))
372+
if len(results) >= item_count:
373+
break
375374
else:
376375
break
377376
if response.errors is not None:

paapi5_python_sdk/__init__.py

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
# coding: utf-8
2+
3+
# flake8: noqa
4+
5+
from __future__ import absolute_import
6+
7+
"""
8+
Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
9+
10+
Licensed under the Apache License, Version 2.0 (the "License").
11+
You may not use this file except in compliance with the License.
12+
A copy of the License is located at
13+
14+
http://www.apache.org/licenses/LICENSE-2.0
15+
16+
or in the "license" file accompanying this file. This file is distributed
17+
on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
18+
express or implied. See the License for the specific language governing
19+
permissions and limitations under the License.
20+
"""
21+
22+
"""
23+
ProductAdvertisingAPI
24+
25+
Generated by: https://github.com/swagger-api/swagger-codegen.git
26+
"""
27+
28+
# import apis into sdk package
29+
from paapi5_python_sdk.api.default_api import DefaultApi
30+
31+
# import auth into sdk package
32+
from paapi5_python_sdk.auth.sig_v4 import AWSV4Auth
33+
34+
# import ApiClient
35+
from paapi5_python_sdk.api_client import ApiClient
36+
from paapi5_python_sdk.configuration import Configuration
37+
# import models into sdk package
38+
from paapi5_python_sdk.availability import Availability
39+
from paapi5_python_sdk.browse_node import BrowseNode
40+
from paapi5_python_sdk.browse_node_ancestor import BrowseNodeAncestor
41+
from paapi5_python_sdk.browse_node_child import BrowseNodeChild
42+
from paapi5_python_sdk.browse_node_children import BrowseNodeChildren
43+
from paapi5_python_sdk.browse_node_info import BrowseNodeInfo
44+
from paapi5_python_sdk.browse_nodes_result import BrowseNodesResult
45+
from paapi5_python_sdk.by_line_info import ByLineInfo
46+
from paapi5_python_sdk.classifications import Classifications
47+
from paapi5_python_sdk.condition import Condition
48+
from paapi5_python_sdk.content_info import ContentInfo
49+
from paapi5_python_sdk.content_rating import ContentRating
50+
from paapi5_python_sdk.contributor import Contributor
51+
from paapi5_python_sdk.delivery_flag import DeliveryFlag
52+
from paapi5_python_sdk.dimension_based_attribute import DimensionBasedAttribute
53+
from paapi5_python_sdk.duration_price import DurationPrice
54+
from paapi5_python_sdk.error_data import ErrorData
55+
from paapi5_python_sdk.external_ids import ExternalIds
56+
from paapi5_python_sdk.get_browse_nodes_request import GetBrowseNodesRequest
57+
from paapi5_python_sdk.get_browse_nodes_resource import GetBrowseNodesResource
58+
from paapi5_python_sdk.get_browse_nodes_response import GetBrowseNodesResponse
59+
from paapi5_python_sdk.get_items_request import GetItemsRequest
60+
from paapi5_python_sdk.get_items_resource import GetItemsResource
61+
from paapi5_python_sdk.get_items_response import GetItemsResponse
62+
from paapi5_python_sdk.get_variations_request import GetVariationsRequest
63+
from paapi5_python_sdk.get_variations_resource import GetVariationsResource
64+
from paapi5_python_sdk.get_variations_response import GetVariationsResponse
65+
from paapi5_python_sdk.image_size import ImageSize
66+
from paapi5_python_sdk.image_type import ImageType
67+
from paapi5_python_sdk.images import Images
68+
from paapi5_python_sdk.item import Item
69+
from paapi5_python_sdk.item_id_type import ItemIdType
70+
from paapi5_python_sdk.item_info import ItemInfo
71+
from paapi5_python_sdk.items_result import ItemsResult
72+
from paapi5_python_sdk.language_type import LanguageType
73+
from paapi5_python_sdk.languages import Languages
74+
from paapi5_python_sdk.manufacture_info import ManufactureInfo
75+
from paapi5_python_sdk.max_price import MaxPrice
76+
from paapi5_python_sdk.merchant import Merchant
77+
from paapi5_python_sdk.min_price import MinPrice
78+
from paapi5_python_sdk.min_reviews_rating import MinReviewsRating
79+
from paapi5_python_sdk.min_saving_percent import MinSavingPercent
80+
from paapi5_python_sdk.multi_valued_attribute import MultiValuedAttribute
81+
from paapi5_python_sdk.offer_availability import OfferAvailability
82+
from paapi5_python_sdk.offer_condition import OfferCondition
83+
from paapi5_python_sdk.offer_count import OfferCount
84+
from paapi5_python_sdk.offer_delivery_info import OfferDeliveryInfo
85+
from paapi5_python_sdk.offer_listing import OfferListing
86+
from paapi5_python_sdk.offer_loyalty_points import OfferLoyaltyPoints
87+
from paapi5_python_sdk.offer_merchant_info import OfferMerchantInfo
88+
from paapi5_python_sdk.offer_price import OfferPrice
89+
from paapi5_python_sdk.offer_program_eligibility import OfferProgramEligibility
90+
from paapi5_python_sdk.offer_promotion import OfferPromotion
91+
from paapi5_python_sdk.offer_savings import OfferSavings
92+
from paapi5_python_sdk.offer_shipping_charge import OfferShippingCharge
93+
from paapi5_python_sdk.offer_sub_condition import OfferSubCondition
94+
from paapi5_python_sdk.offer_summary import OfferSummary
95+
from paapi5_python_sdk.offers import Offers
96+
from paapi5_python_sdk.partner_type import PartnerType
97+
from paapi5_python_sdk.price import Price
98+
from paapi5_python_sdk.product_advertising_api_client_exception import ProductAdvertisingAPIClientException
99+
from paapi5_python_sdk.product_advertising_api_service_exception import ProductAdvertisingAPIServiceException
100+
from paapi5_python_sdk.product_info import ProductInfo
101+
from paapi5_python_sdk.properties import Properties
102+
from paapi5_python_sdk.refinement import Refinement
103+
from paapi5_python_sdk.refinement_bin import RefinementBin
104+
from paapi5_python_sdk.rental_offer_listing import RentalOfferListing
105+
from paapi5_python_sdk.rental_offers import RentalOffers
106+
from paapi5_python_sdk.search_items_request import SearchItemsRequest
107+
from paapi5_python_sdk.search_items_resource import SearchItemsResource
108+
from paapi5_python_sdk.search_items_response import SearchItemsResponse
109+
from paapi5_python_sdk.search_refinements import SearchRefinements
110+
from paapi5_python_sdk.search_result import SearchResult
111+
from paapi5_python_sdk.single_boolean_valued_attribute import SingleBooleanValuedAttribute
112+
from paapi5_python_sdk.single_integer_valued_attribute import SingleIntegerValuedAttribute
113+
from paapi5_python_sdk.single_string_valued_attribute import SingleStringValuedAttribute
114+
from paapi5_python_sdk.sort_by import SortBy
115+
from paapi5_python_sdk.technical_info import TechnicalInfo
116+
from paapi5_python_sdk.trade_in_info import TradeInInfo
117+
from paapi5_python_sdk.trade_in_price import TradeInPrice
118+
from paapi5_python_sdk.unit_based_attribute import UnitBasedAttribute
119+
from paapi5_python_sdk.variation_attribute import VariationAttribute
120+
from paapi5_python_sdk.variation_dimension import VariationDimension
121+
from paapi5_python_sdk.variation_summary import VariationSummary
122+
from paapi5_python_sdk.variations_result import VariationsResult
123+
from paapi5_python_sdk.website_sales_rank import WebsiteSalesRank

paapi5_python_sdk/api/__init__.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# coding: utf-8
2+
3+
# flake8: noqa
4+
5+
from __future__ import absolute_import
6+
7+
"""
8+
Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
9+
10+
Licensed under the Apache License, Version 2.0 (the "License").
11+
You may not use this file except in compliance with the License.
12+
A copy of the License is located at
13+
14+
http://www.apache.org/licenses/LICENSE-2.0
15+
16+
or in the "license" file accompanying this file. This file is distributed
17+
on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
18+
express or implied. See the License for the specific language governing
19+
permissions and limitations under the License.
20+
"""
21+
22+
"""
23+
ProductAdvertisingAPI
24+
25+
Generated by: https://github.com/swagger-api/swagger-codegen.git
26+
"""
27+
28+
# import apis into api package
29+
from paapi5_python_sdk.api.default_api import DefaultApi

0 commit comments

Comments
 (0)