Reputation: 3095
I'm trying to upload a file to S3 by doing :
r_response = requests.post(presigned_post["url"], json=presigned_post["fields"], files=files)
but I'm getting the following error:
Bucket POST must contain a field named 'key'. If it is specified, please check the order of the fields.
But I'm definitely including a key
value. One other answer I saw recommended using a OrderedDict
which I'm trying to do, but looking through the S3 documentation below, I don't see where it specifies a required order for they key,value data when making the request.
http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-HTTPPOSTForms.html http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-authentication-HTTPPOST.html
Anyone have any advice?
Boto3 returns a dictionary with the element values in the following order: x-amz-signature
, x-amz-algorithm
, key
, x-amz-credential
, policy
, and x-amz-date
and I'm just using the same dictionary.
def get_signed_request(title, type, track_id, file):
S3_BUCKET = os.environ.get('S3_BUCKET')
file_name = title
file_type = type
region = 'us-east-1'
s3 = boto3.client('s3', region_name=region, config=Config(signature_version='s3v4'))
presigned_post = s3.generate_presigned_post(
Bucket = S3_BUCKET,
Key = file_name
)
files = {'file': file}
r_response = requests.post(presigned_post["url"], json=presigned_post["fields"], files=files)
Printing the contents of presigned_post
shows the key:
{'fields': {'x-amz-signature': '26eff5417d0d11a25dd294b059a088e2be37a97f14713962f4240c9f4e33febb', 'x-amz-algorithm': 'AWS4-HMAC-SHA256', 'key': u'sound.m4a', 'x-amz-credential': u'<AWSAccessID>/20161011/us-east-1/s3/aws4_request', 'policy': u'eyJjb25kaXRpb25zIjogW3siYnVja2V0IjogImZ1dHVyZWZpbGVzIn0sIHsia2V5IjogInNvdW5kLm00YSJ9LCB7IngtYW16LWFsZ29yaXRobSI6ICJBV1M0LUhNQUMtU0hBMjU2In0sIHsieC1hbXotY3JlZGVudGlhbCI6ICJBS0lBSTdLRktCTkJTNEM0VktKQS8yMDE2MTAxMS91cy1lYXN0LTEvczMvYXdzNF9yZXF1ZXN0In0sIHsieC1hbXotZGF0ZSI6ICIyMDE2MTAxMVQyMDM4NDlaIn1dLCAiZXhwaXJhdGlvbiI6ICIyMDE2LTEwLTExVDIxOjM4OjQ5WiJ9', 'x-amz-date': '20161011T203849Z'}, 'url': u'https://s3.amazonaws.com/bucketname'}
Upvotes: 1
Views: 1010
Reputation: 3095
I was originally doing:
r_response = requests.post(presigned_post["url"], json=presigned_post["fields"], files=files)
I changed the json
to data
and it worked:
r_response = requests.post(presigned_post["url"], data=presigned_post["fields"], files=files)
Unfortunately, I was dealt another 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>
Upvotes: 1