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