Search code examples
python-3.xamazon-web-servicesaws-device-farm

Upload file to AWS Device Farm


I am trying to use python + boto3 to create upload in device farm (uploading a test or an application). The method "create_upload" works fine as it returns an upload arn and url to upload to it.

When I try to use requests to upload file to this URL I get an error:

<Error><Code>SignatureDoesNotMatch</Code><Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message><AWSAccessKeyId>AKIAJV4C3CWPBUMBC3GA</AWSAccessKeyId><StringToSign>AWS4-HMAC-SHA256

My code:

response = client.create_upload(
  projectArn=df_project,
  name="test.zip",
  type="APPIUM_JAVA_TESTNG_TEST_PACKAGE",
  contentType='application/octet-stream'
)
test_url = response["upload"]["url"]
files = {'upload_file': open('/tmp/test.zip','rb')}
r = requests.post(test_url, files=files, data={})

Also i tried using curl, and requests.post passing the file to the data attribut:

r = requests.put(test_url, data=open("/tmp/test.zip", "rb").read())
print(r.text)

and

cmd = "curl --request PUT --upload-file /tmp/test.zip \""+test_url+"\""
result = subprocess.call(cmd, shell=True)
print(result)

Solution

  • I did this before in a past project. Here is a code snippet of how I did it:

    create a new upload

    #http://boto3.readthedocs.io/en/latest/reference/services/devicefarm.html#DeviceFarm.Client.create_upload
    print('Creating the upload presigned url')
    response = client.create_upload(projectArn=args.projectARN,name=str(args.testPackageZip),type='APPIUM_WEB_JAVA_TESTNG_TEST_PACKAGE')
    #create the s3 bucket to store the upload test suite
    uploadArn = response['upload']['arn']
    preSignedUrl = response['upload']['url']
    print('uploadArn: ' + uploadArn + '\n')
    print('pre-signed url: ' + preSignedUrl + '\n')
    
    #print the status of the upload
    #http://boto3.readthedocs.io/en/latest/reference/services/devicefarm.html#DeviceFarm.Client.get_upload
    status = client.get_upload(arn=uploadArn)
    print("S3 Upload Bucket Status: " + status['upload']['status'] + '\n')
    
    print("Uploading file...")
    #open the file and make payload
    payload = {'file':open(args.testPackageZip,'rb')}
    #try and perform the upload
    r = requests.put(url = preSignedUrl,files = payload)
    #print the response code back
    print(r)
    

    Hope that helps