python - Python-Requests 是否支持 OrderedDicts,还是这里出了其他问题?

标签 python post python-requests ordereddictionary

我正在尝试使用 Python 的 Requests 将请求发布到 Amazon S3 终端节点图书馆。该请求属于 multipart/form-data 类型,因为它包含实际文件的 POST。

我正在处理的 API 指定的一个要求是 file参数必须最后发布。由于 Requests 使用字典来 POST multipart/form-data,并且字典不遵循规定的顺序,因此我将其转换为名为 payload 的 OrderedDict 。在发布之前它看起来像这样:

{'content-type': 'text/plain',
 'success_action_redirect':     'https://ian.test.instructure.com/api/v1/files/30652543/create_success?uuid=<opaque_string>',
 'Signature': '<opaque_string>',
 'Filename': '',
 'acl': 'private',
 'Policy': '<opaque_string>',
 'key': 'account_95298/attachments/30652543/log.txt',
 'AWSAccessKeyId': '<opaque_string>',
 'file': '@log.txt'}

这就是我发布它的方式:

r = requests.post("https://instructure-uploads.s3.amazonaws.com/", files = payload)

响应是 500 错误,所以我真的不确定这里的问题是什么。我只是猜测这与我在 Requests 中使用 OrderedDict 有关 - 我找不到任何表明 Requests 支持或不支持 OrderedDicts 的文档。它可能是完全不同的东西。

您还有什么其他问题会导致请求失败吗?如果需要的话我可以提供更多细节。

好的,根据 Martijn Pieters 之前的评论进行更新:

我更改了引用 log.txt 文件的方式,将其添加到已创建的 upload_data 中。像这样的字典:

upload_data['file'] = open("log.txt")

打印生成的字典我得到这个:

{'AWSAccessKeyId': '<opaque_string>',
 'key': '<opaque_string>',
 'Policy': '<opaque_string>',
 'content-type': 'text/plain',
 'success_action_redirect': 'https://ian.test.instructure.com/api/v1/files/30652688/create_success?uuid=<opaque_string>',
 'Signature': '<opaque_string>',
 'acl': 'private',
 'Filename': '',
 'file': <_io.TextIOWrapper name='log.txt' mode='r' encoding='UTF-8'>}

该值是否为 file key 看起来正确吗?

当我将其发布到 RequestBin 时,我得到了这个,它看起来与 Martin 的示例非常相似:

POST /1j92n011 HTTP/1.1
User-Agent: python-requests/1.1.0 CPython/3.3.0 Darwin/12.2.0
Host: requestb.in
Content-Type: multipart/form-data; boundary=e8c3c3c5bb9440d1ba0a5fe11956e28d
Content-Length: 2182
Connection: close
Accept-Encoding: identity, gzip, deflate, compress
Accept: */*

--e8c3c3c5bb9440d1ba0a5fe11956e28d
Content-Disposition: form-data; name="AWSAccessKeyId"; filename="AWSAccessKeyId"
Content-Type: application/octet-stream

<opaque_string>
--e8c3c3c5bb9440d1ba0a5fe11956e28d
Content-Disposition: form-data; name="key"; filename="key"
Content-Type: application/octet-stream

<opaque_string>
--e8c3c3c5bb9440d1ba0a5fe11956e28d
Content-Disposition: form-data; name="Policy"; filename="Policy"
Content-Type: application/octet-stream

<opaque_string>
--e8c3c3c5bb9440d1ba0a5fe11956e28d
Content-Disposition: form-data; name="content-type"; filename="content-type"
Content-Type: application/octet-stream

text/plain
--e8c3c3c5bb9440d1ba0a5fe11956e28d
Content-Disposition: form-data; name="success_action_redirect"; filename="success_action_redirect"
Content-Type: application/octet-stream

https://ian.test.instructure.com/api/v1/files/30652688/create_success?uuid=<opaque_string>
--e8c3c3c5bb9440d1ba0a5fe11956e28d
Content-Disposition: form-data; name="Signature"; filename="Signature"
Content-Type: application/octet-stream

<opaque_string>
--e8c3c3c5bb9440d1ba0a5fe11956e28d
Content-Disposition: form-data; name="acl"; filename="acl"
Content-Type: application/octet-stream

private
--e8c3c3c5bb9440d1ba0a5fe11956e28d
Content-Disposition: form-data; name="Filename"; filename="Filename"
Content-Type: application/octet-stream


--e8c3c3c5bb9440d1ba0a5fe11956e28d
Content-Disposition: form-data; name="file"; filename="log.txt"
Content-Type: text/plain

This is my awesome test file.
--e8c3c3c5bb9440d1ba0a5fe11956e28d--

但是,当我尝试将其 POST 到 https://instructure-uploads.s3.amazonaws.com/ 时,我仍然收到 500 返回值。 。我尝试将打开的文件对象添加到 files然后通过 data 在单独的字典中提交所有其他值,但这也不起作用。

最佳答案

您需要将要发送的内容拆分为传递给 data 的 OrderedDict 和发送给 files 的 OrderedDict。现在,AWS(正确地)将您的数据参数解释为文件,而不是表单参数。它应该看起来像这样:

data = OrderedDict([
    ('AWSAccessKeyId', '<opaque_string>'),
    ('key', '<opaque_string>'),
    ('Policy', '<opaque_string>'),
    ('content-type', 'text/plain'),
    ('success_action_redirect', 'https://ian.test.instructure.com/api/v1/files/30652688/create_success?uuid=<opaque_string>'),
    ('Signature', '<opaque_string>'),
    ('acl', 'private'),
    ('Filename', ''),
])

files = OrderedDict([('file', open('log.txt'))])

requests.post(url, data=data, files=files)

关于python - Python-Requests 是否支持 OrderedDicts,还是这里出了其他问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15504638/

相关文章:

python - 为什么在这个 if 语句中调用变量会给我一个语法错误。我在这里缺少什么规则?

python - 如何从函数内部访问变量

python - 一列的行号,但随后使用另一列重新排序

php - 如何将表单数组值插入 MySQL?

ios - 在 iOS 中使用 JSON 发送 HTTP POST 请求

python - 作为另一个函数的参数的函数

php - CURL 登录并提交另一个帖子

python - 无法从网页上抓取所有公司名称

python - 通过请求获取 cookie

带有参数数据的 Python 请求发布