I am trying to access a web API using a POST technique. I AM able to access it using a GET technique, but the API owners tell me that certain functionality only works with POST. Unfortunately I can't seem to get POST working.
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's what does NOT work with POST (causes 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 anything jump out at anyone as being inherently incorrect in the POST code? I've never done a POST call before but everything I've read seems to suggest that my code is reasonable. Is there some different way I'm supposed to do the add_header thing for the authorization if I'm using POST?
urllib2 is deprecated in python 3. x. use urllib instaed.
Simple urllib2 scripturlopen('http://python.org/') print "Response:", response # Get the URL. This gets the real URL. print "The URL is: ", response. geturl() # Getting the code print "This gets the code: ", response.
True, if you want to avoid adding any dependencies, urllib is available. But note that even the Python official documentation recommends the requests library: "The Requests package is recommended for a higher-level HTTP client interface."
Urllib package is the URL handling module for python. It is used to fetch URLs (Uniform Resource Locators). It uses the urlopen function and is able to fetch URLs using a variety of different protocols. Urllib is a package that collects several modules for working with URLs, such as: urllib.
With urllib2
you need to add the 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)
As @sneeu notes above, it's the act of adding the data to be posted to the request that converts the request from a GET into a POST.
However, this still assumes that what the API is expecting to receive in the POST body is form-encoded data. Many more recent APIs that I've worked with are expecting something else in there (XML or JSON, most commonly).
Can you verify what that API is expecting to receive as a data payload?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With