2014-01-20 21 views
7

我試圖做使用下面的urllib2我計算器上找到的例子入土爲安:否則使用Python PUT的urllib2

Is there any way to do HTTP PUT in python

我不明白爲什麼我得到錯誤的錯誤。

這裏是我的代碼的摘錄:

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

如果我刪除我試圖設置,將其發佈找到看跌期權,但它會出錯誤,當我嘗試設置GET_METHOD放。

爲了確保REST服務不會導致我嘗試使用cURL執行PUT並且它工作正常的問題。

+1

你是什麼例外的全面回溯? –

+3

如果你不想安裝一個新的Python庫,['python-requests'](http://docs.python-requests.org/en/latest/)可以處理'PUT'而不需要額外的入侵,更易於使用。 –

+4

FWIW我強烈建議在Python中使用HTTP請求庫。內置HTTP客戶端功能的API不好。然而,這不等於答案,因爲你的問題指定了'urllib2'。 –

回答

6

正如其他人所指出的,requests是一個了不起的圖書館。但是,如果你是在不能使用requests的情況下(比如一個ansible模塊開發或類似的),還有另外一種方法,通過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) 

用法:

>>> req = MethodRequest(url, method='PUT') 
2

嘗試使用:

import urllib 

data=urllib.urlencode(jsonObj) 

而不是json.dumps。這個對我有用。

2

儘管aaronfay的回答很好,但我認爲考慮到除GET之外只有3種HTTP方法(並且您只關心PUT),只需定義每個請求子類就可以更清楚和更簡單方法。

例如:

class PutRequest(urllib2.Request): 
    '''class to handling putting with urllib2''' 

    def __init__(self, *args, **kwargs): 
     return urllib2.Request.__init__(self, *args, **kwargs) 

    def get_method(self, *args, **kwargs): 
     return 'PUT' 

然後使用:

request = PutRequest(url, data=json.dumps(data), headers=content_header) 
+0

很好地完成了,我同意它更乾淨。 – aaronfay