Using POST and urllib2 to access the web API

I am trying to access the web API using the POST method. I can access it using the GET method, but the API owners tell me that certain functionality only works with POST. Unfortunately, I cannot get POST to work.

Here's what works with GET:

API_URL = "http://example.com/api/" def call_api(method, **kwargs): url = API_URL + method if kwargs: url += '?' + urllib.urlencode(kwargs) req = urllib2.Request(url) auth = 'Basic ' + base64.urlsafe_b64encode("%s:%s" % (USER, PASS)) req.add_header('Authorization', auth) return urllib2.urlopen(req) 

Here is what does NOT work with POST (it causes an HTTP 400 error):

 API_URL = "http://example.com/api/" def call_api(method, **kwargs): url = API_URL + method data='' if kwargs: data=urllib.urlencode(kwargs) req = urllib2.Request(url, data) auth = 'Basic ' + base64.urlsafe_b64encode("%s:%s" % (USER, PASS)) req.add_header('Authorization', auth) return urllib2.urlopen(req) 

Does something jump on someone because it is incorrect in the POST code? I have never made a POST call before, but everything I read seems to suggest that my code is reasonable. Is there any other way that I have to do the add_header thing for authorization if I use POST?

+6
python post urllib2
source share
3 answers

With urllib2 you need to add data to the POST body:

 def call_api(method, **kwargs): url = API_URL + method req = urllib2.Request(url) if kwargs: req.add_data(urllib.urlencode(kwargs)) auth = 'Basic ' + base64.urlsafe_b64encode("%s:%s" % (USER, PASS)) req.add_header('Authorization', auth) # req.get_method() -> 'POST' return urllib2.urlopen(req) 
+9
source share

As @sneeu notes above, this is the action of adding data to be sent to the request, which converts the request from GET to POST.

However, this still assumes that what the API expects to receive in the POST body is the data encoded in the form. Many of the new APIs I've worked with are expecting something else (XML or JSON, most often).

Can you verify what this API expects to receive as a data payload?

+2
source share

I ran into the same problem, I want to send data using the HTTP POST method, but after dir(req) I found get_method but not set_method , and I also found that there is a property called data , try this:

 >>> req.data={"todototry":"123456"} >>> req.get_method() 'POST' >>> 

Thanks @sneeu.

+1
source share

All Articles