我需要PUT
在 python 中使用 HTTP 将一些数据上传到服务器。从我对 urllib2 文档的简要阅读来看,它只做 HTTP POST
。有什么方法可以PUT
在 python 中做一个 HTTP 吗?
14 回答
过去我使用过各种 python HTTP 库,并且我已将请求确定为我的最爱。现有的库具有非常有用的接口,但代码可能最终会变得太长,无法进行简单的操作。请求中的基本 PUT 如下所示:
payload = {'username': 'bob', 'email': 'bob@bob.com'}
>>> r = requests.put("http://somedomain.org/endpoint", data=payload)
然后,您可以使用以下命令检查响应状态代码:
r.status_code
或回复:
r.content
Requests 有很多语法糖和快捷方式,可以让你的生活更轻松。
import urllib2
opener = urllib2.build_opener(urllib2.HTTPHandler)
request = urllib2.Request('http://example.org', data='your_put_data')
request.add_header('Content-Type', 'your/contenttype')
request.get_method = lambda: 'PUT'
url = opener.open(request)
Httplib 似乎是一个更干净的选择。
import httplib
connection = httplib.HTTPConnection('1.2.3.4:1234')
body_content = 'BODY CONTENT GOES HERE'
connection.request('PUT', '/url/path/to/put/to', body_content)
result = connection.getresponse()
# Now result.status and result.reason contains interesting stuff
您可以使用 requests 库,与采用 urllib2 方法相比,它简化了很多事情。首先从 pip 安装它:
pip install requests
更多关于安装请求。
然后设置 put 请求:
import requests
import json
url = 'https://api.github.com/some/endpoint'
payload = {'some': 'data'}
# Create your header as required
headers = {"content-type": "application/json", "Authorization": "<auth-key>" }
r = requests.put(url, data=json.dumps(payload), headers=headers)
请参阅请求库的快速入门。我认为这比 urllib2 简单得多,但确实需要安装和导入这个额外的包。
这在 python3 中做得更好,并记录在stdlib 文档中
该类在python3中urllib.request.Request
获得了一个method=...
参数。
一些示例用法:
req = urllib.request.Request('https://example.com/', data=b'DATA!', method='PUT')
urllib.request.urlopen(req)
你应该看看httplib 模块。它应该允许您发出任何类型的 HTTP 请求。
不久前我也需要解决这个问题,以便我可以充当 RESTful API 的客户端。我选择了 httplib2,因为除了 GET 和 POST 之外,它还允许我发送 PUT 和 DELETE。Httplib2 不是标准库的一部分,但您可以从奶酪店轻松获得它。
我还推荐Joe Gregario 的httplib2。我经常在标准库中使用它而不是 httplib。
你看过put.py吗?我过去用过它。你也可以用 urllib 破解你自己的请求。
您当然可以使用现有的标准库在任何级别上推出自己的标准库,从套接字到调整 urllib。
http://pycurl.sourceforge.net/
“PyCurl 是 libcurl 的 Python 接口。”
“libcurl 是一个免费且易于使用的客户端 URL 传输库,......支持...... HTTP PUT”
“PycURL 的主要缺点是它在 libcurl 之上是一个相对薄的层,没有任何漂亮的 Pythonic 类层次结构。这意味着它的学习曲线有些陡峭,除非你已经熟悉 libcurl 的 C API。”
如果你想留在标准库中,你可以子类化urllib2.Request
:
import urllib2
class RequestWithMethod(urllib2.Request):
def __init__(self, *args, **kwargs):
self._method = kwargs.pop('method', None)
urllib2.Request.__init__(self, *args, **kwargs)
def get_method(self):
return self._method if self._method else super(RequestWithMethod, self).get_method()
def put_request(url, data):
opener = urllib2.build_opener(urllib2.HTTPHandler)
request = RequestWithMethod(url, method='PUT', data=data)
return opener.open(request)
您可以使用requests.request
import requests
url = "https://www.example/com/some/url/"
payload="{\"param1\": 1, \"param1\": 2}"
headers = {
'Authorization': '....',
'Content-Type': 'application/json'
}
response = requests.request("PUT", url, headers=headers, data=payload)
print(response.text)
一个更合适的方法requests
是:
import requests
payload = {'username': 'bob', 'email': 'bob@bob.com'}
try:
response = requests.put(url="http://somedomain.org/endpoint", data=payload)
response.raise_for_status()
except requests.exceptions.RequestException as e:
print(e)
raise
如果 HTTP PUT 请求中有错误,则会引发异常。
使用urllib3
为此,您需要在 URL 中手动编码查询参数。
>>> import urllib3
>>> http = urllib3.PoolManager()
>>> from urllib.parse import urlencode
>>> encoded_args = urlencode({"name":"Zion","salary":"1123","age":"23"})
>>> url = 'http://dummy.restapiexample.com/api/v1/update/15410' + encoded_args
>>> r = http.request('PUT', url)
>>> import json
>>> json.loads(r.data.decode('utf-8'))
{'status': 'success', 'data': [], 'message': 'Successfully! Record has been updated.'}
使用requests
>>> import requests
>>> r = requests.put('https://httpbin.org/put', data = {'key':'value'})
>>> r.status_code
200