使用Python请求在单个请求中发送文件和JSON

时间:2014-07-08 21:41:40

标签: python rest python-requests

我尝试POST到API(使用SlimPHP构建),该API接受图像以及JSON形式的其他图像元数据。

我已经使用REST客户端工具验证了API是否正常工作,并且可以成功POST到服务。所有数据都存储正确。

我现在正尝试使用Python进行POST - 但是我的JSON数据似乎并没有保存。

我的代码:

    data = {'key1': 'value1', 'key2': 'value2'}
    url = 'http://mydomain.com/api/endpoint'
    headers = {'Authorization': 'my-api-key'}
    files = {'file': (FILE, open(PATH, 'rb'), 'image/jpg', {'Expires': '0'})}
    r = requests.post(url, files=files, headers=headers, data=data)

-

我试图设置其他标头,

即:/

headers = {'Authorization': 'unique-auth-key', 'Content-type': 'multipart/form-data'}

headers = {'Authorization': 'unique-auth-key', 'Content-type': 'application/json'}

这导致500错误。


更新2014年7月14日:

使用chrome扩展程序(Advanced Rest Client),我的POST成功 - 这是控制台显示为有效负载的内容:

------WebKitFormBoundarysBpiwrA3hnGPUbMA
Content-Disposition: form-data; name="data"
test
------WebKitFormBoundarysBpiwrA3hnGPUbMA
Content-Disposition: form-data; name="file"; filename="image.jpg"
Content-Type: image/jpeg
------WebKitFormBoundarysBpiwrA3hnGPUbMA--

我不太清楚这意味着什么......

2 个答案:

答案 0 :(得分:16)

您的问题是您使用图像元数据作为要发布的键/值对的来源。而不是将其作为其中一个键/值对的值发送。

以下代码将发送一个请求,就像您提供的curl语句一样:

url = 'my-url.com/api/endpoint'
headers = {'Authorization': 'my-api-key'}
image_metadata = {'key1': 'value1', 'key2': 'value2'}
data = {'name': 'image.jpg', 'data': json.dumps(image_metadata)}
files = {'file': (FILE, open(PATH, 'rb'), 'image/jpg', {'Expires': '0'})}
r = requests.post(url, files=files, headers=headers, data=data)

答案 1 :(得分:0)

如果您需要在单个请求中发布嵌套JSON数据发送文件,则需要使用 json.dumps < / strong>表示这些元素(以下示例中的列表和映射)

{
    "data": [
        {},
        {},
        {},
        {},
        {}
    ]
}

因此将发送如下请求:

import requests

session = requests.Session()
session.post(login_url, json=your_credentials_dict)  # auth , not required
mapping = {"email": "Email", "First Name": "first_name"}
post_data = dict(
   mode=1,
   lists=json.dumps(["133", "899", "911"]),
   mapping=json.dumps(mapping),
)
files_data = {'file': ('your-file-name.csv', file_bytes_content)}
response = session.post(<your-url>, data=post_data, files=files_data)

********** post file data with mapping ********** --> REQUEST: POST /v3/contacts/import/file/ HTTP/1.1 --> REQUEST: Host: <your-host>:4000 --> REQUEST: User-Agent: python-requests/2.23.0 --> REQUEST: Accept-Encoding: gzip, deflate --> REQUEST: Accept: */* --> REQUEST: Connection: keep-alive --> REQUEST: Cookie: jwt=eyJ0e*** --> REQUEST: Content-Length: 654 --> REQUEST: Content-Type: multipart/form-data; boundary=db850c3230988e010b1ebe21be3fb344 --> REQUEST: --> REQUEST: --db850c3230988e010b1ebe21be3fb344 Content-Disposition: form-data; name="lists" ["7syewz9qUz0CbaqhaGm", "LBfWKJwq4Q"] --db850c3230988e010b1ebe21be3fb344 Content-Disposition: form-data; name="mode" 2 --db850c3230988e010b1ebe21be3fb344 Content-Disposition: form-data; name="mapping" {"email": "Email", "First Name": "first_name"} --db850c3230988e010b1ebe21be3fb344 Content-Disposition: form-data; name="file"; filename="good.csv" first_name;last_name;email;age John;Doe;test.testson_1@test.com;50 Mark;Twen;test.testson_2@test.com;20 --db850c3230988e010b1ebe21be3fb344-- 软件包用于生成上面的日志 https://pypi.org/project/requests-toolbelt/