how to match aws signature while sending http post request to aws sagemaker from python(requests), (works from postman)

I have a SageMaker endpoint, which works just as expected from Postman. And I have tried to send the same HTTP POST request from python3(using requests) and cURL, but always get some sort of error, while Postman seems to work fine. I would like to know what I am missing in my Python code and what needs to be added to match the signature properly

Here’s my python3 code to send requests (code from postman ;)):

import requests
import json

url = "https://runtime.sagemaker.ap-south-1.amazonaws.com/endpoints/del-this/invocations"

payload = json.dumps({
 "longitude": [-121.31, -122.37, -120.43, -119.81, -119.82],
 "latitude": [36.42, 37.93, 34.97, 36.83, 36.76],    
 "housing_median_age": [21.0, 37.0, 28.0, 19.0, 46.0],
 "total_rooms": [2740.0, 709.0, 1433.0, 6789.0, 2194.0],
 "total_bedrooms": [615.0, 190.0, 270.0, 1200.0, 563.0],
 "population": [2630.0, 644.0, 1001.0, 2325.0, 924.0],
 "households": [564.0, 174.0, 278.0, 1109.0, 542.0],
 "median_income": [2.6629, 0.8641, 4.0125, 4.049, 1.4028]
 })
headers = {
    'X-Amz-Content-Sha256': 'beaead3198f7da1e70d03ab969765e0821b24fc913697e929e726aeaebf0eba3',
    # i have added some seconds(and experimented with seconsds) to the time after copying code from postman. presumablyly, error didn't generate because of time.
    'X-Amz-Date': '20210829T172003Z',
    'Authorization': 'AWS4-HMAC-SHA256 Credential=AKIA6IWGCDPJPJQ6ADVN/20210829/ap-south-1/sagemaker/aws4_request, SignedHeaders=host;x-amz-content-sha256;x-amz-date, Signature=e49fa86d57f87fa345873c45dbfdb4ed568d38c652c87e1bafd62a7839f6b6b0',
    'Content-Type': 'application/json'
}

response = requests.request("POST", url, headers=headers, data=payload)

print(response.text)

While errors are like:

$ /bin/python3 /home/.../with_requests.py
{"message":"The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details.nnThe Canonical String for this request should have beenn'POSTn/endpoints/del-this/invocationsnnhost:runtime.sagemaker.ap-south-1.amazonaws.comnx-amz-content-sha256:beaead3198f7da1e70d03ab969765e0821b24fc913697e929e726aeaebf0eba3nx-amz-date:20210829T171632Znnhost;x-amz-content-sha256;x-amz-datenad84c4cb0b97ee57a5ad846a3b5763979c226c0c9b06e4dbc825225a4e8958af'nnThe String-to-Sign should have beenn'AWS4-HMAC-SHA256n20210829T171632Zn20210829/ap-south-1/sagemaker/aws4_requestn4adbc056144291d296afdf099e2f131ce06a1b7b49297d05501043f3e9162468'n"}
$ /bin/python3 /home/.../with_requests.py
{"message":"The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details.nnThe Canonical String for this request should have beenn'POSTn/endpoints/del-this/invocationsnnhost:runtime.sagemaker.ap-south-1.amazonaws.comnx-amz-content-sha256:beaead3198f7da1e70d03ab969765e0821b24fc913697e929e726aeaebf0eba3nx-amz-date:20210829T172003Znnhost;x-amz-content-sha256;x-amz-datenad84c4cb0b97ee57a5ad846a3b5763979c226c0c9b06e4dbc825225a4e8958af'nnThe String-to-Sign should have beenn'AWS4-HMAC-SHA256n20210829T172003Zn20210829/ap-south-1/sagemaker/aws4_requestn2aefe46d653941e8a3d0bb07f52b601cab22add39143cd606937039567621383'n"}

Here’s how my postman is set up to send requests to AWS SageMaker:

Authorization tab:

Authorization tab

Headers tab:

Headers tab

Body tab:

Body tab

Yes, both the endpoint and API Keys are no more active, of course. I have made them public only for debugging purposes.

Source: Python Questions

LEAVE A COMMENT