Coder Social home page Coder Social logo

lionheart / bottlenose Goto Github PK

View Code? Open in Web Editor NEW
577.0 37.0 112.0 388 KB

A Python wrapper for the Amazon Product Advertising API.

License: Apache License 2.0

Python 92.35% Makefile 7.65%
amazon-api python amazon-product-advertising bottlenose python-wrapper parsing amazon

bottlenose's Introduction

Version Version License Versions

Bottlenose is a thin, well-tested, maintained, and powerful Python wrapper over the Amazon Product Advertising API. There is practically no overhead, and no magic (unless you add it yourself).

Before you get started, make sure you have both Amazon Product Advertising and AWS accounts. AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY and AWS_ASSOCIATE_TAG are all from your Amazon Associate Account.

Features

  • Compatible with Python versions 2.4 and up
  • Support for AU, BR, CA, CN, DE, ES, FR, IN, IT, JP, MX, UK, and US Amazon Product Advertising API endpoints
  • No requirements, except simplejson for Python versions before 2.6
  • Configurable query parsing
  • Configurable throttling for batches of queries
  • Configurable query caching
  • Configurable error handling and retries

Usage

pip install bottlenose

or

python3 -m pip install bottlenose

Then, using your AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, and AWS_ASSOCIATE_TAG:

import bottlenose
amazon = bottlenose.Amazon(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_ASSOCIATE_TAG)
response = amazon.ItemLookup(ItemId="B007OZNUCE")

You can then parse the response output to view item information.

Troubleshooting

  • If you need help or would like to ask a general question, use Stack Overflow. Apply the 'bottlenose' tag to your question to get help faster.
  • If you found a bug or have a feature request, open an issue.
  • If you want to contribute, submit a pull request. If it's a big change, please open an issue first to discuss implementation.

Advanced Usage

1. Available Search Methods

Region Endpoint

The default Region is set to US (webservices.amazon.com). To specify another endpoint, simply set the Region parameter with the request. For example, to specify the French endpoint (webservices.amazon.fr), set the Region parameter to FR:

amazon = bottlenose.Amazon(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_ASSOCIATE_TAG, Region='FR')

Supported values for the Region parameter are CA, CN, DE, ES, FR, IN, IT, JP, UK, and US (default).

Your Amazon Product Advertising account (AWS_ASSOCIATE_TAG) must exist for the given endpoint, otherwise, you'll get an HTTP 400 error ('Bad Request').

Search for a Specific Item
response = amazon.ItemLookup(ItemId="B007OZNUCE")
Search for Items by Keywords
response = amazon.ItemSearch(Keywords="Kindle 3G", SearchIndex="All")
Search for Images for an item
response = amazon.ItemLookup(ItemId="1449372422", ResponseGroup="Images")
Search for Similar Items
response = amazon.SimilarityLookup(ItemId="B007OZNUCE")

2. Available Shopping Related Methods

Required
amazon = bottlenose.Amazon(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_ASSOCIATE_TAG)
Create a cart
response = amazon.CartCreate(...)
Adding to a cart
response = amazon.CartAdd(CartId, ...)
Get a cart by ID
response = amazon.CartGet(CartId, ...)
Modifying a cart
response = amazon.CartModify(ASIN, CartId,...)
Clearing a cart
response = amazon.CartClear(CartId, ...)

3. Sample Code

import bottlenose
amazon = bottlenose.Amazon(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_ASSOCIATE_TAG)
response = amazon.ItemLookup(ItemId="0596520999", ResponseGroup="Images",
    SearchIndex="Books", IdType="ISBN")
print(response)
# <?xml version="1.0" ?><ItemLookupResponse xmlns="http://webservices.amazon...

Here is another example.

response = amazon.ItemSearch(Keywords="Kindle 3G", SearchIndex="All")
# <?xml version="1.0" ?><ItemSearchResponse xmlns="http://webservices.amazon...

Bottlenose can also read your credentials from the environment automatically; just set $AWS_ACCESS_KEY_ID, $AWS_SECRET_ACCESS_KEY and $AWS_ASSOCIATE_TAG.

Any valid API call from the following is supported (in addition to any others that may be added in the future). Just plug in appropriate request parameters for the operation you'd like to call, and you're good to go.

BrowseNodeLookup
CartAdd
CartClear
CartCreate
CartGet
CartModify
ItemLookup
ItemSearch
SimilarityLookup

You can refer here for a full listing of API calls to be made from Amazon.


For more information about these calls, please consult the Product Advertising API Developer Guide.

Parsing

By default, API calls return the response as a raw bytestring. You can change this with the Parser constructor argument. The parser is a callable that takes a single argument, the response as a raw bytestring, and returns the parsed response in a format of your choice.

For example, to parse responses with BeautifulSoup:

import bottlenose
from bs4 import BeautifulSoup

amazon = bottlenose.Amazon(
    AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_ASSOCIATE_TAG,
    Parser=lambda text: BeautifulSoup(text, 'xml')
)
results = amazon.ItemLookup(ItemId="0198596790", ResponseGroup="SalesRank")

print(results.find('SalesRank').string)
# 168088

Throttling/Batch Mode

Amazon strictly limits the query rate on its API (by default, one query per second per associate tag). If you have a batch of non-urgent queries, you can use the MaxQPS argument to limit them to no more than a certain rate; any faster, and bottlenose will sleep() until it is time to make the next API call.

Generally, you want to be just under the query limit, for example:

amazon = bottlenose.Amazon(MaxQPS=0.9)

If some other code is also querying the API with your associate tag (for example, a website backend), you'll want to choose an even lower value for MaxQPS.

Caching

You can often get a major speedup by caching API queries. Use the CacheWriter and CacheReader constructor arguments.

CacheWriter is a callable that takes two arguments, a cache url, and the raw response (a bytestring). It will only be called after successful queries.

CacheReader is a callable that takes a single argument, a cache url, and returns a (cached) raw response, or None if there is nothing cached.

The cache url is the actual query URL with authentication information removed. For example:

http://webservices.amazon.com/onca/xml?Keywords=vacuums&Operation=ItemSearch&Region=US&ResponseGroup=SearchBins&SearchIndex=All&Service=AWSECommerceService&Version=2013-08-01

Example code:

def write_query_to_db(cache_url, data):
    ...

def read_query_from_db(cache_url):
    ...

amazon = bottlenose.Amazon(CacheWriter=write_query_to_db,
                           CacheReader=read_query_from_db)

Note that Amazon's Product Advertising API Agreement only allows you to cache queries for up to 24 hours.

Error Handling

Sometimes the Amazon API returns errors; for example, if you have gone over your query limit, you'll get a 503. The ErrorHandler constructor argument gives you a way to keep track of such errors, and to retry queries when you receive a transient error.

ErrorHandler should be a callable that takes a single argument, a dictionary with these keys:

  • api_url: the actual URL used to call the API
  • cache_url: api_url minus authentication information
  • exception: the exception raised (usually an HTTPError or URLError)

If your ErrorHandler returns true, the query will be retried. Here's some example code that does exponential backoff after throttling:

import random
import time
from urllib2 import HTTPError

def error_handler(err):
    ex = err['exception']
    if isinstance(ex, HTTPError) and ex.code == 503:
        time.sleep(random.expovariate(0.1))
        return True

amazon = bottlenose.Amazon(ErrorHandler=error_handler)

License

Apache License, Version 2.0. See LICENSE for details.

bottlenose's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

bottlenose's Issues

Change Marketplace

Associate ID and access to the API is restricted to the Marketplace (Locale) in which the Associate account was registered. How to change the Marketplace/Locale in this wrapper? For example: I can only access the Indian Market place since I've created an associate account there.

issues with xslt in example (just a heads up)

I know the xml2json xslt isn't yours, but I just wanted to mention what seems to be a bug I came across when following your example, just in case it helps anyone else out. I made two ItemSearch queries with the same info, one with and one without the xslt, and it seems only the first Item entry shows up in the json version. Here is my query:

<Request>
  <IsValid>True</IsValid>
  <ItemSearchRequest>
    <Keywords>mustang</Keywords>
    <ResponseGroup>Small</ResponseGroup>
    <SearchIndex>KindleStore</SearchIndex>
  </ItemSearchRequest>
</Request>

And here are the example files:

confused about the credentials

the credentials are confusing me, so there is AWS but there is also MWS, my intention is to get things like the Best Sellers Rank of an ASIN, can I use bottlenose for that?

All I have is MWS account, I can register for the AWS credential from amazon associate but there is a limitation of "You must drive at least three qualified sales within 180 days in order to avoid termination of your Associate account." for amazon associates program (where I can get the API)

Is it possible to use bottlenose for MWS related activities such as GetMatchingProductForId? I tried to no avail but it could be im passing incorrect credentials (using MWS) to bottlenose

bottlenose 1.0.0 issue - python 3.5 - "NameError: name 'execfile' is not defined"

Tried to upgrade to bottlenose 1.0.0 released recently.

$ pip install --upgrade bottlenose
Collecting bottlenose
  Downloading bottlenose-1.0.0.tar.gz
    Complete output from command python setup.py egg_info:
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "/tmp/pip-build-m0r2s65g/bottlenose/setup.py", line 27, in <module>
        execfile("bottlenose/metadata.py", metadata)
    NameError: name 'execfile' is not defined

    ----------------------------------------
Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-build-m0r2s65g/bottlenose/
(local3) $ pip --version
pip 8.1.2 from /home/user/python3.5/site-packages (python 3.5)
(local3) $ python --version
Python 3.5.2

This is an issue only with python 3.5(.x) and not 2.7.x - FYI . 

cache example

Hi, i try to use the cache function with bottlenose ...

def reader(cache_url):
    return cache.ram(cache_url,lambda: None,time_expire=86400) #Time expire can be any value you want (3600 = 1hour)

def writer(cache_url, response_text):
    cache.ram(cache_url,lambda: response_text,time_expire=0) #Time Expire always 0 here

i'm very new to python and i don't know what to import for the chache.ram function :(

can you help me ?

Thanks

gzip & deflate support?

Hi dlo, I really like your bottlenose. Do you think it's possible to add gzip and/or deflate support? I'm using my own hack with gzip, but still wanted to know if you plan to do that in the future. Thanks.

iPython crashes when hitting TAB to find an object of type bottlenose.Amazon properties

Using iPython 0.11 and Python 2.7.

I'm doing the following in iPython:

a = bottlenose.Amazon(AMAZON_ACCESS_KEY_ID, AMAZON_SECRET_KEY, AMAZON_ASSOC_TAG)
a.

After typing a. I hit TAB and iPython crashes

a.ERROR: An unexpected error occurred while tokenizing input
The following traceback may be corrupted or invalid
The error message is: ('EOF in multi-line statement', (14, 0)) 

bottlenose init function casts strings as tuples on Python 2.7

Using Python 2.7 on Ubuntu trusty64 I'm getting the following error:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python2.7/dist-packages/bottlenose/api.py", line 250, in __call__
    api_url = self.api_url(**kwargs)
  File "/usr/local/lib/python2.7/dist-packages/bottlenose/api.py", line 180, in api_url
    digest = hmac.new(self.AWSSecretAccessKey, data, sha256).digest()
  File "/usr/lib/python2.7/hmac.py", line 133, in new
    return HMAC(key, msg, digestmod)
  File "/usr/lib/python2.7/hmac.py", line 71, in __init__
    key = key + chr(0) * (blocksize - len(key))
TypeError: can only concatenate tuple (not "str") to tuple

I resolved this error by running the following code after initializing the bottlenose object:

amazon.AWSAccessKeyId = amazon.AWSAccessKeyId[0]                                       
amazon.AWSSecretAccessKey = amazon.AWSSecretAccessKey[0]                               
amazon.AssociateTag = amazon.AssociateTag[0]

support for Python 3?

I get:
Traceback (most recent call last):
File "../Python/BiMiSt/testJSON.py", line 12, in
response = searchISBN()
File "../Python/BiMiSt/testJSON.py", line 10, in searchISBN
Style="http://xml2json-xslt.googlecode.com/svn/trunk/xml2json.xslt"))
File "C:\Python32\lib\site-packages\bottlenose-0.4.0-py3.2.egg\bottlenose\api.py", line 100, in call
keys.sort()
AttributeError: 'dict_keys' object has no attribute 'sort'

if i use bottlenose unter python 3.2.2 / Win7(64bit)

Help needed regarding AWS IAM for using bottlenose

Forgive me for asking this here, as this is not really an issue with the code.
I want to know what AWS IAM permissions are needed to allow using bottlenose. I created a user in AWS IAM and gave him some permissions, but when I tried using bottlenose I get an error 'Unauthorized 401'.

So what permissions should I give the user for querying products using bottlenose?

Thank you

help() causes TypeError

When I call help(amazon) I get the following error

Python 2.7.2 |EPD 7.1-2 (32-bit)| (default, Jul 27 2011, 13:29:32) 
[GCC 4.0.1 (Apple Inc. build 5493)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> amazon = bottlenose.Amazon(AMAZON_ACCESS_KEY_ID, AMAZON_SECRET_KEY, AMAZON_ASSOC_TAG)
>>> help(amazon)
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/Library/Frameworks/Python.framework/Versions/7.1/lib/python2.7/site.py", line 467, in __call__
    return pydoc.help(*args, **kwds)
  File "/Library/Frameworks/Python.framework/Versions/7.1/lib/python2.7/pydoc.py", line 1727, in __call__
    self.help(request)
  File "/Library/Frameworks/Python.framework/Versions/7.1/lib/python2.7/pydoc.py", line 1771, in help
    else: doc(request, 'Help on %s:')
  File "/Library/Frameworks/Python.framework/Versions/7.1/lib/python2.7/pydoc.py", line 1511, in doc
    pager(render_doc(thing, title, forceload))
  File "/Library/Frameworks/Python.framework/Versions/7.1/lib/python2.7/pydoc.py", line 1488, in render_doc
    if name and '.' in name:
TypeError: argument of type 'AmazonCall' is not iterable

The problem is that AmazonCall.__getattr__ interprets Amazon.__name__ as an Amazon API call instead of raising AttributeError. Pydoc calls __name__ expecting to receive either a string or AttributeError, which leads to the error in the traceback. Perhaps double-underscore methods should be exempt from the special __getattr__ handling.

Error 400

Hi there! I'm new to using the Amazon API, and I successfully implemented bottlenose last week. Now, when I'm testing I get HttpError: 400 Bad Request! Any idea why this would be happening?

I double checked that my AWS keys and associate tags were all correct, and I used the example search. But still no luck.

exception HTTP Error 400: Bad Request

Hi all,

I'm using your library to lookup in the Amazon database using the ASIN, I'm using the same code for 3 different regions (using 2 API keys, one for a region and one shared by 2 regions) and until today everything worked fine.

However, starting from today, the requests made with the API key shared among the 2 regions raise the exception: HTTP Error 400: Bad Request.

This sounds really strange to me since the same code worked until yesterday and the same code still work for the other region with the other API key.

This is the call:

region.amazon.ItemLookup(ItemId=keyword, IdType="ASIN", ResponseGroup="ItemAttributes,Offers,Images")

It's strange also because it doesn't' raise an exception with status code 502 or 503 (too many requests, it would make sense), but a 400.

Any idea?
Thanks

TypeError: argument of type 'NoneType' ... from example code

Hi,

I'm trying to use this in Python 3.4 and am getting the following error.

>>> response = amazon.ItemSearch(Keywords="Kindle 3G", SearchIndex="All")
Traceback (most recent call last):
  File "<pyshell#6>", line 1, in <module>
    response = amazon.ItemSearch(Keywords="Kindle 3G", SearchIndex="All")
  File "C:\Python34\lib\site-packages\bottlenose\api.py", line 246, in __call__
    if "gzip" in response.info().get("Content-Encoding"):
TypeError: argument of type 'NoneType' is not iterable

I'm not sure if this is an actual bug or if it is me doing something wrong. I am using the following code:

import bottlenose

AWS_ACCESS_KEY_ID = "I've got the key"
AWS_SECRET_ACCESS_KEY = "I've got the secret"
AWS_ASSOCIATE_TAG = "I've got the tag"

amazon = bottlenose.Amazon(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_ASSOCIATE_TAG)

response = amazon.ItemSearch(Keywords="Kindle 3G", SearchIndex="All")
print(response)

and this is pretty much the example code. Installed using pip, Python 3.4

I'm not sure if this is an IAM issue so I've checked using my root keys, and the same issue persists.

Any ideas what could be causing this?

Many thanks

(PS: yes, actual Amazon IAM credentials going in the variables)

400 error

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Library/Python/2.7/site-packages/bottlenose/api.py", line 251, in __call__
    {'api_url': api_url, 'cache_url': cache_url})
  File "/Library/Python/2.7/site-packages/bottlenose/api.py", line 212, in _call_api
    return urllib2.urlopen(api_request, timeout=self.Timeout)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 154, in urlopen
    return opener.open(url, data, timeout)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 437, in open
    response = meth(req, response)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 550, in http_response
    'http', request, response, code, msg, hdrs)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 475, in error
    return self._call_chain(*args)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 409, in _call_chain
    result = func(*args)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 558, in http_error_default
    raise HTTPError(req.get_full_url(), code, msg, hdrs, fp)
urllib2.HTTPError: HTTP Error 400: Bad Request

Cannot connect to german "DE" region

Hey guys,

I followed your installtion / setup-instructions but cannot connect to the amazon product API. Either I'll get a 400 or 503 error code.

The only thing I don't get: If I only need my data from my associate account

Before you get started, make sure you have both Amazon Product Advertising and AWS accounts. AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY and AWS_ASSOCIATE_TAG are all from your Amazon Associate Account.

why do I need an AWS account? Currently I'm using the key, secret key and associate tag from my amazon associate account and it doesn't work, unfortunately. I also tried to generate the same keys, except the associate key, within my AWS account and tried to connect but without any success. Can you explain why we need both accounts? (AWS and Associates)

I haven't set a payment option within my AWS account but I'm able to use it and create my keys. May this be a problem?

I'm really looking forward for any kind of help. It's really needed.

Thanks guys for contributing, really appreciate it.

Best regards

search example

Could you add an example to search books?

response=amazon.ItemSearch(
    SearchIndex='Books', Author='Richard Dawkins',
    Style="http://xml2json-xslt.googlecode.com/svn/trunk/xml2json.xslt")
response = json.loads(response)
print json.dumps(response, sort_keys=True, indent=4)

Update readme example to use modified xml2json.xslt

See: https://github.com/dlo/bottlenose/issues/2

The example on the bottlenose readme still includes the URI to the "broken" XSLT:

Style="http://xml2json-xslt.googlecode.com/svn/trunk/xml2json.xslt")

Can we add an attribution link in the readme for the xml2json.xslt Google code project, and then change the example Style to point to the new xml2json.xslt file?

Style="http://raw.github.com/dlo/bottlenose/00b7b6eabfd51ed580a644ffb697c65ce2f0568b/xml2json.xslt")

Http 403 error bottlenose python (Amazon API)

I am trying to access data using Amazon's API. I created product advertisement and aws account with same email and password, got the aws_secret, aws_key and affiliate_associate_key.

Then, I tried the following:

import bottlenose
aws_key = 'my_aws_key'
aws_secret = 'my_aws_secret' 
aws_associate_tag = 'my_aws_associate_tag'

amazon = bottlenose.Amazon(aws_key, aws_secret, aws_associate_tag)
product = amazon.lookup(ItemId='B00EOE0WKQ')

And, I get the HTTP 403 error as follows (I added some print statement in my urllib2.py file):

message from urllib2.py Forbidden
headers from urllib2.py Date: Sun, 21 Aug 2016 05:44:59 GMT
Server: Apache-Coyote/1.1
Vary: Accept-Encoding,User-Agent
Content-Encoding: gzip
Content-Length: 304
Keep-Alive: timeout=2, max=15
Connection: Keep-Alive

code from urllib2.py 403
---------------------------------------------------------------------------
HTTPError                                 Traceback (most recent call last)
<ipython-input-1-973306797553> in <module>()
      5 
      6 amazon = bottlenose.Amazon(aws_key, aws_secret, aws_associate_tag)
----> 7 product = amazon.lookup(ItemId='B00EOE0WKQ')
      8 

/Users/chaitra/anaconda/lib/python2.7/site-packages/bottlenose/api.pyc in __call__(self, **kwargs)
    263         # make the actual API call
    264         response = self._call_api(api_url,
--> 265                                   {'api_url': api_url, 'cache_url': cache_url})
    266 
    267         # decompress the response if need be

/Users/chaitra/anaconda/lib/python2.7/site-packages/bottlenose/api.pyc in _call_api(self, api_url, err_env)
    224                 else:
    225                     # the simple way
--> 226                     return urllib2.urlopen(api_request, timeout=self.Timeout)
    227             except:
    228                 if not self.ErrorHandler:

/Users/chaitra/anaconda/lib/python2.7/urllib2.py in urlopen(url, data, timeout, cafile, capath, cadefault, context)
    152     else:
    153         opener = _opener
--> 154     return opener.open(url, data, timeout)
    155 
    156 def install_opener(opener):

/Users/chaitra/anaconda/lib/python2.7/urllib2.py in open(self, fullurl, data, timeout)
    438         for processor in self.process_response.get(protocol, []):
    439             meth = getattr(processor, meth_name)
--> 440             response = meth(req, response)
    441 
    442         return response

/Users/chaitra/anaconda/lib/python2.7/urllib2.py in http_response(self, request, response)
    551         if not (200 <= code < 300):
    552             response = self.parent.error(
--> 553                 'http', request, response, code, msg, hdrs)
    554 
    555         return response

/Users/chaitra/anaconda/lib/python2.7/urllib2.py in error(self, proto, *args)
    476         if http_err:
    477             args = (dict, 'default', 'http_error_default') + orig_args
--> 478             return self._call_chain(*args)
    479 
    480 # XXX probably also want an abstract factory that knows when it makes

/Users/chaitra/anaconda/lib/python2.7/urllib2.py in _call_chain(self, chain, kind, meth_name, *args)
    410             func = getattr(handler, meth_name)
    411 
--> 412             result = func(*args)
    413             if result is not None:
    414                 return result

/Users/chaitra/anaconda/lib/python2.7/urllib2.py in http_error_default(self, req, fp, code, msg, hdrs)
    559 class HTTPDefaultErrorHandler(BaseHandler):
    560     def http_error_default(self, req, fp, code, msg, hdrs):
--> 561         raise HTTPError(req.get_full_url(), code, msg, hdrs, fp)
    562 
    563 class HTTPRedirectHandler(BaseHandler):

HTTPError: HTTP Error 403: Forbidden

Things tried:

I made sure that all the keys and the associate_tag are infact from the same account.
I also synced clock on my machine (which was in Central timezone) to sync to N.California timezone.
I have made around 5 requests in over an hour.

I am using Python v 2.7.11 and running this code using Anaconda's QtConsole on my machine locally.

Appreciate any help!

CartCreate

CartCreate take request parameters in form of:

Item.1.OfferListingId = xxxx

which is not a valid python kwarg keyword, therefore CartCreate can not be invoked.
I am posting a workaround by allowing call taking a dictionary in argument argDict.

--- a/pythonsource/bottlenose/api.py
+++ b/pythonsource/bottlenose/api.py
@@ -53,10 +53,19 @@ class AmazonCall(object):
         else:
             service_domain = SERVICE_DOMAINS[self.Region][0]
 
-        keys = kwargs.keys()
+        reqargs = {}
+
+        for k in kwargs.keys():
+          if k == "argDict": 
+            for kk in kwargs[k].keys():
+              reqargs[kk] = kwargs[k][kk]
+          else:
+            reqargs[k] = kwargs[k]
+
+        keys = reqargs.keys()
         keys.sort()
 
-        quoted_strings = "&".join("%s=%s" % (k, urllib.quote(str(kwargs[k]).encode('utf-8'), safe = '~')) for k in keys)
+        quoted_strings = "&".join("%s=%s" % (k, urllib.quote(str(reqargs[k]).encode('utf-8'), safe = '~')) for k in keys)
 
         data = "GET\n" + service_domain + "\n/onca/xml\n" + quoted_strings

Not able to fetch the price

Not sure this is the right place to post, but I am not able to fetch the price of an item. I am using Variations, OfferSummary, Offers as response groups. Following is the code :

import bottlenose
amazon = bottlenose.Amazon('ACCESS_KEY', 'SECRET_KEY', 'ASSOCIATE_TAG')
response = amazon.ItemLookup(ItemId="B00CP8V1Y4", ResponseGroup="Variations,OfferSummary,Offers")
print response

and following is the response I am getting :

<ItemLookupResponse xmlns="http://webservices.amazon.com/AWSECommerceService/2011-08-01">
<OperationRequest>
<HTTPHeaders>
<Header Name="UserAgent" Value="Python-urllib/2.7"/>
</HTTPHeaders>
<RequestId>5d3d496c-ca40-4687-8f50-7a816b0afd9e</RequestId>
<Arguments>
<Argument Name="Operation" Value="ItemLookup"/>
<Argument Name="Service" Value="AWSECommerceService"/>
<Argument Name="Signature" Value=""/>
<Argument Name="AssociateTag" Value=""/>
<Argument Name="Version" Value="2011-08-01"/>
<Argument Name="ItemId" Value="B00CP8V1Y4"/>
<Argument Name="AWSAccessKeyId" Value=""/>
<Argument Name="Timestamp" Value="2013-08-04T16:30:55Z"/>
<Argument Name="ResponseGroup" Value="Variations,OfferSummary,Offers"/>
</Arguments>
<RequestProcessingTime>0.0358110000000000</RequestProcessingTime>
</OperationRequest>
<Items>
<Request>
<IsValid>True</IsValid>
<ItemLookupRequest>
<IdType>ASIN</IdType>
<ItemId>B00CP8V1Y4</ItemId>
<ResponseGroup>Variations</ResponseGroup>
<ResponseGroup>OfferSummary</ResponseGroup>
<ResponseGroup>Offers</ResponseGroup>
<VariationPage>All</VariationPage>
</ItemLookupRequest>
</Request>
<Item>
<ASIN>B00CP8V1Y4</ASIN>
</Item>
</Items>
</ItemLookupResponse>

Enhanced documentation tutorials

I think the README lacks sufficient examples for the general user basis. I wish to contribute added documentation on how to perform various searches and the code to go along with it.

Also, i recommend we implement lxml and objectify for parsing the responses.

A release?

Hey any chance of a point release? I just revisited a project and had to debug an issue with HMAC and unicode.. Only to discover I fixed this already 6 months ago :D

3ff57a2

On CartAdd: "Your request is missing required parameters. Required parameters include HMAC."

I'm trying to add an element to a cart I created.

I have:

kwargs = {
   "CartId" = "xxxx",
   "Item.0.OfferListingId" = "yyyy",
   "Item.0.Quantity" = 1 
}

new_cart = amazon.CartAdd(**kwargs)

With amazon defined as amazon = bottlenose.Amazon(AWSAccessKeyId, AWSSecretKey, AWSAssociateTag)

The response says:

Your request is missing required parameters. Required parameters include HMAC.

Is it a bug or am I doing something wrong?

Adding code templates for users

This is a continuation from a previous post. #24

The goal is to create sample templates that users can download for accessing the Amazon API.

In addition, I believe we could streamline the process of data retrieval by creating methods that return json formatted data (or XML formatted). <-- perhaps have that as an option.

Examples:

import bottlenose

response = amazon.ItemLookup(ItemId="1449372422", ResponseGroup="Images")

images = bottlenose.parseImages(response)

for image in images:
    print image.URL

BAD REQUEST ERROR

I am trying to execute the sample code provided on your github page.

amazon = bottlenose.Amazon(AMAZON_ACCESS_KEY, AMAZON_SECRET_KEY, AMAZON_ASSOC_TAG)
response = amazon.ItemSearch(Keywords="Kindle 3G", SearchIndex="All")
print(response)

I am getting the following error. Any suggestion how to resolve this error?

Traceback (most recent call last):
  File "C:\Product\workspace\eclipse\ls.batch\batch\utils\amazon.py", line 13, in <module>
    response = amazon.ItemSearch(Keywords="Kindle 3G", SearchIndex="All")
  File "C:\Users\Roy Debajyoti.BCGCOM\AppData\Local\Programs\Python\Python36-32\lib\site-packages\bottlenose\api.py", line 265, in __call__
    {'api_url': api_url, 'cache_url': cache_url})
  File "C:\Users\Roy Debajyoti.BCGCOM\AppData\Local\Programs\Python\Python36-32\lib\site-packages\bottlenose\api.py", line 226, in _call_api
    return urllib2.urlopen(api_request, timeout=self.Timeout)
  File "C:\Users\Roy Debajyoti.BCGCOM\AppData\Local\Programs\Python\Python36-32\lib\urllib\request.py", line 223, in urlopen
    return opener.open(url, data, timeout)
  File "C:\Users\Roy Debajyoti.BCGCOM\AppData\Local\Programs\Python\Python36-32\lib\urllib\request.py", line 532, in open
    response = meth(req, response)
  File "C:\Users\Roy Debajyoti.BCGCOM\AppData\Local\Programs\Python\Python36-32\lib\urllib\request.py", line 642, in http_response
    'http', request, response, code, msg, hdrs)
  File "C:\Users\Roy Debajyoti.BCGCOM\AppData\Local\Programs\Python\Python36-32\lib\urllib\request.py", line 570, in error
    return self._call_chain(*args)
  File "C:\Users\Roy Debajyoti.BCGCOM\AppData\Local\Programs\Python\Python36-32\lib\urllib\request.py", line 504, in _call_chain
    result = func(*args)
  File "C:\Users\Roy Debajyoti.BCGCOM\AppData\Local\Programs\Python\Python36-32\lib\urllib\request.py", line 650, in http_error_default
    raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 400: Bad Request

How to add ERROR HANDLER to active Bottlenose connection

I am getting 503's.
According to your instructions, I need to add a error_handler as per instructions.
in the instructions I placed the function:

def error_handler(err):
    ex = err['exception']
    if isinstance(ex, HTTPError) and ex.code == 503:
        time.sleep(random.expovariate(0.1))
        return True

Your instruction says use this line:

amazon = bottlenose.Amazon(ErrorHandler=error_handler)

I have this:

amazon = bottlenose.Amazon(AWSAccessKeyId=ACCESS_KEY_ID, AWSSecretAccessKey = SECRET_KEY,AssociateTag = ASSOC_TAG)

I tried to add the option several ways, such as this:

amazon = bottlenose.Amazon(AWSAccessKeyId=ACCESS_KEY_ID, AWSSecretAccessKey = SECRET_KEY,AssociateTag = ASSOC_TAG,ErrorHandler=error_handler)

But I'm still getting 503's. I assume I am not setting it right.
I'm hoping you might be able to tell me where I am missing this.
Thank you

Change API version to 2013-08-01

Amazon document indicates that current version is 2013-08-01 and best practices document advice to use latest version.

"The Product Advertising API uses the default API version 2013-08-01 unless you supply a different value for the Version parameter. To use a different version, you must include it in the Version parameter in your requests."
Amazon Advertising API Best Practices

urllib.error.HTTPError: HTTP Error 400: Bad Request

response = amazon.ItemSearch(Keywords="Kindle 3G", SearchIndex="All")
  File "/usr/local/lib/python3.4/dist-packages/bottlenose/api.py", line 265, in __call__
    {'api_url': api_url, 'cache_url': cache_url})
  File "/usr/local/lib/python3.4/dist-packages/bottlenose/api.py", line 226, in _call_api
    return urllib2.urlopen(api_request, timeout=self.Timeout)
  File "/usr/lib/python3.4/urllib/request.py", line 153, in urlopen
    return opener.open(url, data, timeout)
  File "/usr/lib/python3.4/urllib/request.py", line 461, in open
    response = meth(req, response)
  File "/usr/lib/python3.4/urllib/request.py", line 571, in http_response
    'http', request, response, code, msg, hdrs)
  File "/usr/lib/python3.4/urllib/request.py", line 499, in error
    return self._call_chain(*args)
  File "/usr/lib/python3.4/urllib/request.py", line 433, in _call_chain
    result = func(*args)
  File "/usr/lib/python3.4/urllib/request.py", line 579, in http_error_default
    raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 400: Bad Request

I have the same issue with Python 2. What could it be?

Add Region to examples

Maybe it's just me but it took me some time to figure out that to set endpoints one simply has to add Region to the request, as such:

amazon = bottlenose.Amazon(AWS_KEY, AWS_SECRET, AWS_TAG, Region='FR')

Could this maybe be added in the tutorial somewhere?

Inconsistent querying with 503 Errors

Hi there,

I've been playing around with bottlenose, using a forloop to loop over products on my website and check whether prices are up to date.

The issue is that I've been experiencing 503 errors, but in a totally random sequence. Sometimes I run the command and it works, other times it doesn't work, and sometimes it works for a few loops and then throws the error. I have experimented extensively with tweaking the MaxQPS settings and the only time it works consistently is when MaxQPS=0.1 but this is devilishly slow, especially when I'm having to query hundreds of items.

Any idea why this could be? Thanks in advance

(P.S. Awesome work on bottlenose, it's top notch!)

EDIT Naturally, now that I have posted this, the MaxQPS=0.1 is also now acting inconsistently, occasionally throwing 503 errors! Sigh

CartCreate : Required parameters include Items

While Create New Cart:-
Get Your request is missing required parameters. Required parameters include Items.

data = {
            'offer_id': "59PwDdXajXbVuCLg6kd7QZDCA2hWxjO%2FXqhLLQcJDzOe4mAm%2FIaKuy94kleD682oMmHsvFlXmM5guvCSnCTfaQuqU9PN%2Fq4%2Fwmm73RqOuFV9FePGy8fq4g%3D%3D",
            'quantity': 2
}
response = amazon.CartCreate(items=data)

Get Response as below:-

<?xml version="1.0" encoding="UTF-8"?>
<CartCreateResponse xmlns="http://webservices.amazon.com/AWSECommerceService/2013-08-01">
   <OperationRequest>
      <HTTPHeaders>
         <Header Name="UserAgent" Value="Python-urllib/2.7" />
      </HTTPHeaders>
      <RequestId>0f8f191a-f546-4d2b-9eb4-297f575920c1</RequestId>
      <Arguments>
         <Argument Name="AWSAccessKeyId" Value="AKIAJTJOIACOYJSJC5EA" />
         <Argument Name="AssociateTag" Value="caupd4125k-21" />
         <Argument Name="Operation" Value="CartCreate" />
         <Argument Name="Service" Value="AWSECommerceService" />
         <Argument Name="Timestamp" Value="2018-04-24T10:59:39Z" />
         <Argument Name="Version" Value="2013-08-01" />
         <Argument Name="items" Value="{'offer_id': u'59PwDdXajXbVuCLg6kd7QZDCA2hWxjO%2FXqhLLQcJDzOe4mAm%2FIaKuy94kleD682oMmHsvFlXmM5guvCSnCTfaQuqU9PN%2Fq4%2Fwmm73RqOuFV9FePGy8fq4g%3D%3D', 'quantity': u'1'}" />
         <Argument Name="Signature" Value="g9PToXIDjSrnV5CQgaEsj5I1zpiAYg8cgu/I1lxIh1A=" />
      </Arguments>
      <RequestProcessingTime>1.26464E-4</RequestProcessingTime>
   </OperationRequest>
   <Cart>
      <Request>
         <IsValid>False</IsValid>
         <CartCreateRequest>
            <Items />
         </CartCreateRequest>
         <Errors>
            <Error>
               <Code>AWS.MissingParameters</Code>
               <Message>Your request is missing required parameters. Required parameters include Items.</Message>
            </Error>
         </Errors>
      </Request>
   </Cart>
</CartCreateResponse>

As AWS documentation
image

https://docs.aws.amazon.com/AWSECommerceService/latest/DG/CartCreate.html#CartCreate-rp

Support for Amazon AU

Amazon just opened a store in Australia. Can we please get support for AU. Currently getting the error when I try:

  File "/home/nathan/venv_rb/lib/python3.4/site-packages/bottlenose/api.py", line 252, in __call__
    cache_url = self.cache_url(**kwargs)
  File "/home/nathan/venv_rb/lib/python3.4/site-packages/bottlenose/api.py", line 209, in cache_url
    service_domain = SERVICE_DOMAINS[self.Region][0]
KeyError: 'AU'

Product Advertising API Amazon

Hi,

My name is Duc, my job is developer website. I need a Product Advertising API Associate account, but I can not register because I do not have an online shop. I just need it to get the products of amazon. You can sell or share account Associate ?

Sorry for my English is not good

Thanks!

Error: expected string or bytes-like object

I'm running my code on a server, and the connection to Amazon works correct when I first boot at the server, but after some requests it fails all the time. If I restart the server it starts working again, but then fails on the same previous situation. I've tried changing the IP from the server, to check if my IP was blocked. But that wasn't the case. I'm not getting a clear error from the API, only an empty object error, so I can't figure out how to solve the issue.

Here is the error:

Traceback (most recent call last):
  File "/usr/local/lib/python3.5/dist-packages/amazon/api.py", line 174, in lookup
    response = self.api.ItemLookup(ResponseGroup=ResponseGroup, **kwargs)
  File "/usr/local/lib/python3.5/dist-packages/bottlenose/api.py", line 274, in __call__
    {'api_url': api_url, 'cache_url': cache_url})
  File "/usr/local/lib/python3.5/dist-packages/bottlenose/api.py", line 235, in _call_api
    return urllib2.urlopen(api_request, timeout=self.Timeout)
  File "/usr/lib/python3.5/urllib/request.py", line 163, in urlopen
    return opener.open(url, data, timeout)
  File "/usr/lib/python3.5/urllib/request.py", line 466, in open
    response = self._open(req, data)
  File "/usr/lib/python3.5/urllib/request.py", line 484, in _open
    '_open', req)
  File "/usr/lib/python3.5/urllib/request.py", line 444, in _call_chain
    result = func(*args)
  File "/usr/lib/python3.5/urllib/request.py", line 1297, in https_open
    context=self._context, check_hostname=self._check_hostname)
  File "/usr/lib/python3.5/urllib/request.py", line 1254, in do_open
    h.request(req.get_method(), req.selector, req.data, headers)
  File "/usr/lib/python3.5/http/client.py", line 1107, in request
    self._send_request(method, url, body, headers)
  File "/usr/lib/python3.5/http/client.py", line 1147, in _send_request
    self.putheader(hdr, value)
  File "/usr/lib/python3.5/http/client.py", line 1083, in putheader
    if _is_illegal_header_value(values[i]):
TypeError: expected string or bytes-like object

Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.