Deca Deca - 3 months ago 23
reST (reStructuredText) Question

400 Bad Request With urllib2 for POST

I am struggling from 2 days with a post request to be made only using urllib & urllib2. I have limitations in using curl or requests library, as the machine I would need to deploy my code doesn't support any of these.

The post call would be accompanied with a Header and json Body. I am able to make any get call, but POST with Data & Header throws 400 bad requests. Tried and applied all the options available in google/stackoverflow, but nothing solved!

Below is the sample code:--

import urllib
import urllib2

url = 'https://1.2.3.4/rest/v1/path'
headers = {'X-Auth-Token': '123456789sksksksk111',
'Content-Type': 'application/json'}
body = {'Action': 'myaction',
'PressType': 'Format1', 'Target': '/abc/def'}
data = urllib.urlencode(body)
request = urllib2.Request(url, data, headers)
response = urllib2.urlopen(request, data)


And on setting debug handler, below is the format of the request that can be traced:--

send: 'POST /rest/v1/path HTTP/1.1\r\nAccept-Encoding: identity\r\nContent-Length: 52\r\nHost: 1.2.3.4\r\nUser-Agent: Python-urllib/2.7\r\nConnection: close\r\nX-Auth-Token: 123456789sksksksk111\r\nContent-Type: application/json\r\n\r\nAction=myaction&PressType=Format1&Target=%2Fabc%2Fdef'

reply: 'HTTP/1.1 400 Bad Request\r\n'


Please note, the same post request works perfectly fine with any REST client and with Requests library. In the debug handler output, if we see, the json structure is Content-Type:
application/json\r\n\r\nAction=myaction&PressType=Format1&Target=%2Fabc%2Fdef
, can that be a problem!

Answer

You can dump the json instead of encoding it. I was facing the same and got solved with it!

Remove data = urllib.urlencode(body) and use urllib2.urlopen(req, json.dumps(data))

That should solve.