I'm trying to do PUT to REST using urllib2 following the example I found on stackoverflow:
Is there any way to do HTTP PUT in python
I don't understand why I get error an error.
Here's an excerpt of my code:
import urllib2
import json
content_header = {'Content-type':'application/json',
'Accept':'application/vnd.error+json,application/json',
'Accept-Version':'1.0'}
baseURL = "http://some/put/url/"
f = open("somefile","r")
data = json.loads(f.read())
request = urllib2.Request(url=baseURL, data=json.dumps(jsonObj), headers=content_header)
request.get_method = lambda: 'PUT' #if I remove this line then the POST works fine.
response = urllib2.urlopen(request)
print response.read()
if I remove the PUT option I'm trying to set then it posts it find but it will error out when I try and set get_method to PUT.
To be sure that the REST services aren't causing the issues I tried using cURL to do a PUT and it worked fine.
urllib2 is a Python module that can be used for fetching URLs. It defines functions and classes to help with URL actions (basic and digest authentication, redirections, cookies, etc) The magic starts with importing the urllib2 module.
A Gentle Introduction URL stands for Uniform Resource Locator. Basically, URL is used to identify a resource on the internet. In order to fetch an URL from the internet and use the data within the URL, the urllib2 standard python module was being used in Python2.
# Prepare the data query_args = { 'q':'query string', 'foo':'bar' } # This urlencodes your data (that's why we need to import urllib at the top) data = urllib.urlencode(query_args) # Send HTTP POST request request = urllib2.Request(url, data) response = urllib2.urlopen(request) html = response.read() # Print the result print html User Agents
In order to fetch an URL from the internet and use the data within the URL, the urllib2 standard python module was being used in Python2. The urllib2 module supported a lot of functions and classes that helped the users to open an URL and extract the contents.
While aaronfay's answer is good and works, I think that given that there are only 3 HTTP methods other than GET (and you are only worried about PUT), it is clearer and simpler to just define the Request sub-classes per method.
For example:
class PutRequest(urllib2.Request):
'''class to handling putting with urllib2'''
def get_method(self, *args, **kwargs):
return 'PUT'
Then to use:
request = PutRequest(url, data=json.dumps(data), headers=content_header)
As others have noted, requests
is a fantastic library. However, if you are in a situation where requests
cannot be used (say an ansible module development or similar), there is another way, as demonstrated by the author of this gist:
import urllib2
class MethodRequest(urllib2.Request):
def __init__(self, *args, **kwargs):
if 'method' in kwargs:
self._method = kwargs['method']
del kwargs['method']
else:
self._method = None
return urllib2.Request.__init__(self, *args, **kwargs)
def get_method(self, *args, **kwargs):
if self._method is not None:
return self._method
return urllib2.Request.get_method(self, *args, **kwargs)
Usage:
>>> req = MethodRequest(url, method='PUT')
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