使用python请求用文件POST数据

时间:2017-12-11 14:25:16

标签: python curl file-upload python-requests

我有以下工作卷曲

curl -v -i -H "Content-Type:multipart/form-data" -H "X-Authorization: 12345" -F "file0=@/path/to/image.jpg" -d 'jsonData={ "data": { "field1": 1, "field2": 2 } }' -X POST http://example.com/url/path

我正在尝试在python中提出完全相同的请求,并提出以下

    headers = {
        'Content-Type': 'multipart/form-data',
        'X-Authorization': '12345',
    }

    files = {
        'file0': ('/path/to/image.jpg',
                  open('/path/to/image.jpg', 'rb')),

    }

    file_post = requests.post('http://example.com/url/path',
                                headers=headers,
                                files=files,
                                data={
                                    "jsonData": {
                                        "data": {
                                            "field1": 1,
                                            "field2": 2,
                                        }
                                    }
                                })

问题是我对curl和python有不同的响应。这些请求不相同或者我应该在其他地方寻找吗?

1 个答案:

答案 0 :(得分:0)

你不能只是传入Python字典而不将其编码为JSON。您的curl帖子具有jsonData表单字段的JSON编码数据,因此您的Python代码需要提供相同的内容:

import json

headers = {'X-Authorization': '12345'}

files = {
    'file0': ('/path/to/image.jpg',
              open('/path/to/image.jpg', 'rb')),
}
file_post = requests.post(
    'http://example.com/url/path',
    headers=headers,
    files=files,
    data={
        "jsonData": json.dumps({
            "data": {
                "field1": 1,
                "field2": 2,
            }
        })
    })

通过将字典传递给data,每个是一个可迭代的,被视为一系列单独的值(因此{'data': ['foo', 'bar']}被转换为{{1 }})。您传入了data=foo&data=bar键的字典,这是一个可迭代的,因此处理了一系列值。最终你只发布了jsonData,没有别的。

通过使用(JSON编码的)单个值,您可以告诉请求直接传递该值,作为jsonData=data键的值。

使用jsonData关键字参数也会触发正确的files标题,不需要手动设置。