2009年7月18日土曜日

[Python] Amazonへの署名付きリクエスト

再びAmazonへのリクエストネタ。

今まではAmazonへのリクエストはアクセスキー(秘密鍵とは別)さえあれば、本の詳細情報やレビューとかの公開されたデータは、誰でもリクエストで取得できた。
けど、8月15日から全てのリクエストについて、署名なしリクエストは受けてくれなくなるそう。

しょうがないので、以下のサイトを参考に対応。
Amazon Product Advertising APIの署名認証をPythonでやってみる

以下が更新したAmazonリクエスト取得用メソッド。
色々なタイプのデータを取りに行くので、こんな形にしてる。
英語がめちゃくちゃなのは・・・もはや標準仕様ということで<汗

==================================================
import urllib
import hashlib, hmac, base64
from datetime import datetime

AWS_SECRET_ACCESS_KEY = 自分の秘密鍵
AWS_ACCESS_KEY_ID = 自分のアクセスキー
AWS_JP_URI = 'ecs.amazonaws.jp'
AWS_JP_ENDPOINT = '/onca/xml'
AWS_VERSION = '2008-08-19'

def getAmazonXML(search_options):
  """
  与えられたオプションからAmazonへのリクエストを作成・実行
  XMLを取得する
  Makes a request to Amazon from the given search_options and executes it.
  XML is acquired.
  """

  # 全てのリクエストに共通するリクエストパラメータ
  # Common request parameter to all Amazon request
  options = {'Service' :'AWSECommerceService',
       'AWSAccessKeyId' : AWS_ACCESS_KEY_ID,
       'Version' : AWS_VERSION,
       'Timestamp' : datetime.utcnow().isoformat(),
       }

  # optionsにsearch_optionsを追加(連想配列の結合はupdate())
  # search_options is added to options (if samekey exists, updated)
  options.update(search_options)

  # リクエストはバイト順にソートした上でURLエンコード
  # その後、正規表現より+を%20(quote処理)に変更
  # Request is sorted based on bytedata, and urlencoded.
  # And "+" is replaced with "%20"(quote)
  query = urllib.urlencode(sorted(options.items())).replace("+", "%20")

  # 署名の作成
  # generate signature
  text = '\n'.(['GET', AWS_JP_URI, AWS_JP_ENDPOINT, query]) # target of signature
  signature = base64.b64encode(hmac.new(AWS_SECRET_ACCESS_KEY, text, hashlib.sha256).digest())

  # 署名のリクエストへの追加とURLエンコード
  # make url for Japan Amazon ECS
  request_url = "http://" + AWS_JP_URI + AWS_JP_ENDPOINT
  request_url += "?" + query + "&" + urllib.urlencode({'Signature': signature})

  # リクエストの実行
  # execute request
  xml = urllib.urlopen(request_url).read()
  
  return xml

==================================================

なんか、随分メンドくさくなっちゃったな。。。
ってか、あとAS3も対応しなきゃいけないんだった。。。あう。

0 件のコメント: