codeBarer
codeBarer

Reputation: 2378

Doing PUT using Python urllib2

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.

Upvotes: 9

Views: 17431

Answers (3)

Rob Marrowstone
Rob Marrowstone

Reputation: 1264

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)

Upvotes: 13

Ruben
Ruben

Reputation: 172

Try to use:

import urllib

data=urllib.urlencode(jsonObj)

Instead of json.dumps. It works for me.

Upvotes: 0

aaronfay
aaronfay

Reputation: 1692

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')

Upvotes: 10

Related Questions