Python请求:在单个请求中发布JSON和文件

ozn*_*znu 28 python json urllib2

我需要进行API调用以上传文件以及带有文件详细信息的JSON字符串.

我试图使用python请求lib来做到这一点:

import requests

info = {
    'var1' : 'this',
    'var2'  : 'that',
}

data = json.dumps({
    'token' : auth_token,
    'info'  : info,
})

headers = {'Content-type': 'multipart/form-data'}

files = {'document': open('file_name.pdf', 'rb')}

r = requests.post(url, files=files, data=data, headers=headers)
Run Code Online (Sandbox Code Playgroud)

这会引发以下错误:

    raise ValueError("Data must not be a string.")
 ValueError: Data must not be a string
Run Code Online (Sandbox Code Playgroud)

如果我从请求中删除"文件",它就可以了.
如果我从请求中删除"数据",它就可以工作.
如果我不将数据编码为JSON,则可以正常工作.

出于这个原因,我认为错误与在同一请求中发送JSON数据和文件有关.

关于如何使这个工作的任何想法?

pro*_*eer 19

不要使用json进行编码.

import requests

info = {
    'var1' : 'this',
    'var2'  : 'that',
}

data = {
    'token' : auth_token,
    'info'  : info,
}

headers = {'Content-type': 'multipart/form-data'}

files = {'document': open('file_name.pdf', 'rb')}

r = requests.post(url, files=files, data=data, headers=headers)
Run Code Online (Sandbox Code Playgroud)

请注意,这可能不一定是您想要的,因为它将成为另一个表单数据部分.

  • 这只有在`data`是简单的键值对(类似于参数)时才有效,但是所有嵌套的东西都会被截断,因为HTTP表单编码不能表示嵌套的数据结构. (5认同)
  • @proteneer 这似乎对我不起作用,做一个像 . `d = requests.post('http://localhost:18090/upload',files={ 'face_image': ('mama_justkilled_aman.jpg', open('mama_justkilled_aman.jpg', 'rb'), 'image/jpeg ' ) }, data={ 'gffp': 42 })` 但服务器未收到数据 (2认同)
  • @BalaKrishna 也不适合我,服务器看不到数据:( (2认同)

ral*_*htp 14

请参阅此主题如何将JSON作为多部分POST请求的一部分发送

不要自己设置Content-type标头,将其留给pyrequests生成

def send_request():
payload = {"param_1": "value_1", "param_2": "value_2"}
files = {
     'json': (None, json.dumps(payload), 'application/json'),
     'file': (os.path.basename(file), open(file, 'rb'), 'application/octet-stream')
}

r = requests.post(url, files=files)
print(r.content)
Run Code Online (Sandbox Code Playgroud)

  • @MouIdri 它将是 ```request.form['json']``` (3认同)
  • 假设 Flask 是接收者,为此编写 Flask 的方法是什么? (2认同)
  • 这对我有用,但是我们如何在其中发送多个文件? (2认同)