0

alexa topsites サービスにアクセスしようとしています。それに基づいて、Alexaのドキュメントからコードをコピーしました。

コードは以下のとおりです。

import sys, os, base64, datetime, hashlib, hmac 
import requests 



method = 'GET'
service = "AlexaTopSites"
host = "ats.amazonaws.com"
region = 'us-east-1'
endpoint = "ats.us-east-1.amazonaws.com"



request_parameters="Action=TopSites&Count=100&CountryCode=BR&ResponseGroup=Country&Start=301&Url=yahoo.com"




def sign(key, msg):
    return hmac.new(key, msg.encode('utf-8'), hashlib.sha256).digest()

def getSignatureKey(key, dateStamp, regionName, serviceName):
    kDate = sign(('AWS4' + key).encode('utf-8'), dateStamp)
    kRegion = sign(kDate, regionName)
    kService = sign(kRegion, serviceName)
    kSigning = sign(kService, 'aws4_request')
    return kSigning


access_key = AWS_ACCESS_KEY_ID
secret_key = AWS_SECRET_KEY



t = datetime.datetime.utcnow()
amzdate = t.strftime('%Y%m%dT%H%M%SZ')
datestamp = t.strftime('%Y%m%d') # Date w/o time, used in credential scope



canonical_uri = '/' 
canonical_querystring = request_parameters
canonical_headers = 'host:' + host + '\n' + 'x-amz-date:' + amzdate + '\n'
signed_headers = 'host;x-amz-date'
payload_hash = hashlib.sha256(('').encode('utf-8')).hexdigest()
canonical_request = method + '\n' + canonical_uri + '\n' + canonical_querystring + '\n' + canonical_headers + '\n' + signed_headers + '\n' + payload_hash



algorithm = 'AWS4-HMAC-SHA256'
credential_scope = datestamp + '/' + region + '/' + service + '/' + 'aws4_request'
string_to_sign = algorithm + '\n' +  amzdate + '\n' +  credential_scope + '\n' +  hashlib.sha256(canonical_request.encode('utf-8')).hexdigest()


signing_key = getSignatureKey(secret_key, datestamp, region, service)


signature = hmac.new(signing_key, (string_to_sign).encode('utf-8'), hashlib.sha256).hexdigest()


authorization_header = algorithm + ' ' + 'Credential=' + access_key + '/' + credential_scope + ', ' +  'SignedHeaders=' + signed_headers + ', ' + 'Signature=' + signature

headers = {'Authorization':authorization_header,"Content-Type":"application/xml",'X-Amz-Date':amzdate, "Accept":"application/xml"}


url="https://ats.amazonaws.com/api"+"?"+request_parameters

r = requests.get(url, headers=headers)
r.text

エラーメッセージは以下

<?xml version="1.0" ?>\n<aws:TopSitesResponse xmlns:aws="http://ats.amazonaws.com/doc/2005-10-05">\n  <aws:Response xmlns:aws="http://ats.amazonaws.com/doc/2005-07-11">\n    <aws:OperationRequest>\n      <aws:RequestId></aws:RequestId>\n    </aws:OperationRequest>\n    <aws:TopSitesResult>\n      <aws:Alexa>\n        <aws:Request>\n          <aws:Errors>\n            <aws:Error>\n              <aws:ErrorCode><![CDATA["Credential should be scoped to a valid region, not \'us-east-1\'. "]]></aws:ErrorCode>\n            </aws:Error>\n          </aws:Errors>\n        </aws:Request>\n      </aws:Alexa>\n    </aws:TopSitesResult>\n    <aws:ResponseStatus xmlns:aws="http://alexa.amazonaws.com/doc/2005-10-05/">\n      <aws:StatusCode>Error</aws:StatusCode>\n    </aws:ResponseStatus>\n  </aws:Response>\n</aws:TopSitesResponse>

正確なエラーコードは以下です

<aws:ErrorCode><![CDATA["Credential should be scoped to a valid region, not \'us-east-1\'. "]]>

実際、私は IAM ユーザーを削除し、aws のドキュメントに従って何度も再作成しましたが、喜びはありません。地域は正しいと思います。多くの異なる AWS リージョンを試しましたが、うまくいきませんでした。

私はパラメータ(service = "blablalba"、host="blablalba"、endpoint = "blalbalba")をいじりました。引数に渡すパラメータに関係なく、エラー応答は常に同じです。エラーは常に同じです。

method = 'GET'
service = "AlexaTopSites"
host = "ats.amazonaws.com"
region = 'us-east-1'
endpoint = "ats.us-east-1.amazonaws.com"

エラーコードのみ変化するのはリージョン部分です。region = "hohoho" を入力すると、次のようなエラー応答が返されます

"Credential should be scoped to a valid region, not \'hohoho\'. "

PS: 私は AWS マーケットプレイスの TopSites サービスに加入しています。

4

1 に答える 1