BSP BSP - 1 month ago 5
reST (reStructuredText) Question

Request.put method gets 500 response when using data={...} argument, and 200 response when using json={...} argument instead. Why?

res = requests.put(url=self.URL, json=self.output) # gives <Response [200]>
res = requests.put(url=self.URL, data=self.output) # gives <Response [500]>


This is an example of the dictionary I am trying to upload:

{u'RPT6': '22,4', u'RPT7': '13,2', u'RPT4': '4,1', u'RPT5': '13,1', u'RPT2': '18,4', u'RPT3': '7,1', u'RPT1': '1,1', 'Last Change Time': '2017/09/19 - 16:24:28', u'RPT8': '5,1', u'RPT9': '10,3', '
Last Change Author': 'CNBCN477QB', u'RPT10': '22,4', u'RPT11': '22,3', u'RPT12': '15,3'}


This dictonary is a modification of an original json file obtained from the same url
www.myjson.com
using
requests.get
method. Therefore I understand there is no problem with the server. After cheaking the related documentation I am not able to discover why I get that error as it is clearly stated that the use of a dictionary goes with the
data
argument.

Answer Source

The difference is that the data parameter will form-encode your data while the json parameter will send json formated data.

Let's see what the server recieves using the data parameter:

data = {'key 1':'a string', 'key 2': 2, 'key 3':True}
res = requests.put('http://somesite.com', data=data)

print(res.request.method + ' / HTTP/1.1')
print('\r\n'.join(': '.join(i) for i in res.request.headers.items()))
print()
print(res.request.body)

PUT / HTTP/1.1
Connection: keep-alive
Accept-Encoding: gzip, deflate
Accept: /
User-Agent: python-requests/2.18.1
Content-Length: 33
Content-Type: application/x-www-form-urlencoded

key+1=a+string&key+2=2&key+3=True


Now let's send the same data with the json parameter:

data = {'key 1':'a string', 'key 2': 2, 'key 3':True}
res = requests.put('http://somesite.com', json=data)

print(res.request.method + ' / HTTP/1.1')
print('\r\n'.join(': '.join(i) for i in res.request.headers.items()))
print()
print(res.request.body)

PUT / HTTP/1.1
Connection: keep-alive
Accept-Encoding: gzip, deflate
Accept: /
User-Agent: python-requests/2.18.1
Content-Length: 48
Content-Type: application/json

{"key 1": "a string", "key 2": 2, "key 3": true}

As you can see the HTTP request is very different in both cases.