python请求

python请求,python,json,python-requests,html-post,Python,Json,Python Requests,Html Post,我正在为RESTful API POST谓词编写测试,它将多部分表单数据发送到服务器。 我想对数据进行json编码。正确的方法是什么? 下面是3个测试,其中前两个通过,第三个(我需要的场景)失败。任何帮助都将不胜感激 import requests import json print "test 1, files+data/nojson" requests.post('http://localhost:8080', files={'spot[photo]': open('test.jpg',

我正在为RESTful API POST谓词编写测试,它将多部分表单数据发送到服务器。 我想对数据进行json编码。正确的方法是什么? 下面是3个测试,其中前两个通过,第三个(我需要的场景)失败。任何帮助都将不胜感激

import requests
import json

print "test 1, files+data/nojson"
requests.post('http://localhost:8080', files={'spot[photo]': open('test.jpg', 'rb')}, data={'spot': 'spot_description'})

print "test 2, only data/json"
requests.post('http://localhost:8080',data=json.dumps({'spot': 'spot_description'}))

print "test 3, only files+data/json"
requests.post('http://localhost:8080', files={'spot[photo]': open('test.jpg',
'rb')}, data=json.dumps({'spot': 'spot_description'}))
代码输出:

$ /cygdrive/c/Python27/python.exe -B test.py
test 1, files+data/nojson
test 2, only data/json
test 3, only files+data/json
Traceback (most recent call last):
  File "test.py", line 12, in <module>
    'rb')}, data=json.dumps({'spot': 'spot_description'}))
  File "C:\Python27\lib\site-packages\requests\api.py", line 98, in post
    return request('post', url, data=data, **kwargs)
  File "C:\Python27\lib\site-packages\requests\safe_mode.py", line 39, in wrapped
    return function(method, url, **kwargs)
  File "C:\Python27\lib\site-packages\requests\api.py", line 51, in request
    return session.request(method=method, url=url, **kwargs)
  File "C:\Python27\lib\site-packages\requests\sessions.py", line 241, in request
    r.send(prefetch=prefetch)
  File "C:\Python27\lib\site-packages\requests\models.py", line 532, in send
    (body, content_type) = self._encode_files(self.files)
  File "C:\Python27\lib\site-packages\requests\models.py", line 358, in _encode_files
    fields = to_key_val_list(self.data)
  File "C:\Python27\lib\site-packages\requests\utils.py", line 157, in to_key_val_list
    raise ValueError('cannot encode objects that are not 2-tuples')
ValueError: cannot encode objects that are not 2-tuples
$/cygdrive/c/Python27/python.exe-B test.py
测试1,文件+数据/nojson
测试2,仅数据/json
测试3,仅文件+数据/json
回溯(最近一次呼叫最后一次):
文件“test.py”,第12行,在
'rb')},data=json.dumps({'spot':'spot_description'}))
文件“C:\Python27\lib\site packages\requests\api.py”,第98行,在post中
返回请求('post',url,data=data,**kwargs)
文件“C:\Python27\lib\site packages\requests\safe\u mode.py”,第39行,包装为
返回函数(方法、url、**kwargs)
文件“C:\Python27\lib\site packages\requests\api.py”,第51行,在请求中
return session.request(method=method,url=url,**kwargs)
文件“C:\Python27\lib\site packages\requests\sessions.py”,第241行,在请求中
r、 发送(预回迁=预回迁)
文件“C:\Python27\lib\site packages\requests\models.py”,第532行,在send中
(正文,内容类型)=self.\u编码文件(self.files)
文件“C:\Python27\lib\site packages\requests\models.py”,第358行,在_encode_文件中
字段=到键值列表(self.data)
文件“C:\Python27\lib\site packages\requests\utils.py”,第157行,在to\u key\u val\u列表中
raise VALUERROR('无法对非2元组的对象进行编码')
ValueError:无法对非2元组的对象进行编码
错误是因为
数据
参数是字符串

models.py::send()中

models.py::_encode_files()

utils.py::to_key\u val\u list()中

这是通过self.data在通话中遇到的问题。您正在传入字典的字符串表示形式,但它需要字典本身,如下所示:

requests.post('http://localhost:8080',
              files={'spot[photo]': open('test.jpg', 'rb')},
              data={'spot': 'spot_description'})
因此,如果将任何内容分配给文件参数,则数据参数的类型不能是str、bytes、bool或int。您可以在源代码中进行后续操作:

POST
ing JSON数据可以通过将其嵌入如下表单编码字段来解决:

post(url, data={'data': json.dumps(actual_data)}, files={'myfile': open('foo.data')})
post(url, files={'data': json.dumps(actual_data), 'myfile': open('foo.dat')})
另外,我认为您可以像这样将所有内容放入
文件中:

post(url, data={'data': json.dumps(actual_data)}, files={'myfile': open('foo.data')})
post(url, files={'data': json.dumps(actual_data), 'myfile': open('foo.dat')})

…这应该相当于第一个代码段。

我的猜测(没有时间测试)是,当您传递文件IO容器时,您只是传递它
open('test.jpg','rb')
。您需要通过实际的bytestream,
open('test.jpg','rb').read()
。我明天会检查这个。这听起来不正确,因为传递文件和简单的数据字典实际上是有效的。这听起来很合理,但留下了几个问题:1。为什么如果我不使用“文件”,它会起作用2我应该怎么做才能将请求主体json我编辑了我的答案来解释第一个问题的答案。至于第二个问题,我不确定在请求模块中是否可以。非常感谢您的努力。我对你的答案投了赞成票,但我没有接受,因为我仍然希望对我的主要问题有一个更好的答案。
post(url, files={'data': json.dumps(actual_data), 'myfile': open('foo.dat')})