what is the required order for S3 element values when making a Post request?
<p>I'm trying to upload a file to S3 by doing :</p>

<pre><code>r_response = requests.post(presigned_post["url"], json=presigned_post["fields"], files=files)
</code></pre>

<p>but I'm getting the following error:</p>

<blockquote>
  <p>Bucket POST must contain a field named 'key'.  If it is specified, please check the order of the fields.</p>
</blockquote>

<p>But I'm definitely including a <code>key</code> value.  One other answer I saw recommended using a <code>OrderedDict</code> 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.  </p>

<p><a href="http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-HTTPPOSTForms.html" rel="nofollow">http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-HTTPPOSTForms.html</a>
<a href="http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-authentication-HTTPPOST.html" rel="nofollow">http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-authentication-HTTPPOST.html</a></p>

<p>Anyone have any advice?</p>

<p>Boto3 returns a dictionary with the element values in the following order: <code>x-amz-signature</code>, <code>x-amz-algorithm</code>, <code>key</code>, <code>x-amz-credential</code>, <code>policy</code>, and <code>x-amz-date</code> and I'm just using the same dictionary.</p>

<pre><code>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)
</code></pre>

<p>Printing the contents of <code>presigned_post</code> shows the key:</p>

<pre><code> {'fields': {'x-amz-signature': '26eff5417d0d11a25dd294b059a088e2be37a97f14713962f4240c9f4e33febb', 'x-amz-algorithm': 'AWS4-HMAC-SHA256', 'key': u'sound.m4a', 'x-amz-credential': u'&lt;AWSAccessID&gt;/20161011/us-east-1/s3/aws4_request', 'policy': u'eyJjb25kaXRpb25zIjogW3siYnVja2V0IjogImZ1dHVyZWZpbGVzIn0sIHsia2V5IjogInNvdW5kLm00YSJ9LCB7IngtYW16LWFsZ29yaXRobSI6ICJBV1M0LUhNQUMtU0hBMjU2In0sIHsieC1hbXotY3JlZGVudGlhbCI6ICJBS0lBSTdLRktCTkJTNEM0VktKQS8yMDE2MTAxMS91cy1lYXN0LTEvczMvYXdzNF9yZXF1ZXN0In0sIHsieC1hbXotZGF0ZSI6ICIyMDE2MTAxMVQyMDM4NDlaIn1dLCAiZXhwaXJhdGlvbiI6ICIyMDE2LTEwLTExVDIxOjM4OjQ5WiJ9', 'x-amz-date': '20161011T203849Z'}, 'url': u'https://s3.amazonaws.com/bucketname'}
</code></pre>

<p>I was originally doing:</p>

<pre><code>r_response = requests.post(presigned_post["url"], json=presigned_post["fields"], files=files)
</code></pre>

<p>I changed the <code>json</code> to <code>data</code> and it worked:</p>

<pre><code>r_response = requests.post(presigned_post["url"], data=presigned_post["fields"], files=files)
</code></pre>

<p>Unfortunately, I was dealt another error:</p>

<p><code>&lt;Error&gt;&lt;Code&gt;SignatureDoesNotMatch&lt;/Code&gt;&lt;Message&gt;The request signature we calculated does not match the signature you provided. Check your key and signing method.&lt;/Message&gt;</code></p>

python amazon-s3 boto3