Accessing Amazon’s Product Advertising API with Python

I’m working on a little hacky toy for our upcoming hack day at work, and one of the pieces requires that I get some info from the Amazon “REST” API. It’s not REST in the least, but that’s not what I’m here to talk about. I’m here to talk about creating a signed request which works with the “Amazon Signature 2” format needed for the API. There’s a Perl library to do everything with the API, which is great if that’s what you’re looking for, but it wasn’t. I just wanted to sign a simple static request to get information about books for which I had the ISBN. No Python library exists, but fortunately if you’re using Python 2.5+ you’ve got everything you need with very little code. I’m including it here to save you the effort of pulling together the pieces yourself.

# Create a signed request to use Amazon's APInimport base64nimport hmacnimport urllib, urlparsenimport time</code>nnfrom hashlib import sha256 as sha256nnAWS_ACCESS_KEY_ID = 'XXX'nAWS_SECRET_ACCESS_KEY = 'YYY'nhmac = hmac.new(AWS_SECRET_ACCESS_KEY, digestmod=sha256)nndef getSignedUrl(params):n    action = 'GET'n    server = "webservices.amazon.com"n    path = "/onca/xml"nn    params['Version'] = '2009-11-02'n    params['AWSAccessKeyId'] = AWS_ACCESS_KEY_IDn    params['Service'] = 'AWSECommerceService'n    params['Timestamp'] = time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime())nn    # Now sort by keys and make the param stringn    key_values = [(urllib.quote(k), urllib.quote(v)) for k,v in params.items()]n    key_values.sort()nn    # Combine key value pairs into a string.n    paramstring = '&'.join(['%s=%s' % (k, v) for k, v in key_values])n    urlstring = "http://" + server + path + "?" + \n        ('&'.join(['%s=%s' % (k, v) for k, v in key_values]))nn    # Add the method and path (always the same, how RESTy!) and get it ready to signn    hmac.update(action + "\n" + server + "\n" + path + "\n" + paramstring)nn    # Sign it up and make the url stringn    urlstring = urlstring + "&Signature="+\n        urllib.quote(base64.encodestring(hmac.digest()).strip())nn    return urlstringnnif __name__ == "__main__":n    params = {'ResponseGroup':'Small,BrowseNodes,Reviews,EditorialReview,AlternateVersions',n                     'AssociateTag':'xxx-20',n                     'Operation':'ItemLookup',n                     'SearchIndex':'Books', n                     'IdType':'ISBN',n                     'ItemId':'9780385086950'}n    url = getSignedUrl(params)n    print urln

nn

Similar Posts