Merge branch 'develop' of github.com:kennethreitz/requests into develop

This commit is contained in:
Kenneth Reitz
2012-03-22 15:00:51 -04:00
14 changed files with 104 additions and 63 deletions
+4
View File
@@ -88,3 +88,7 @@ Patches and Suggestions
- Chris Dary
- Danver Braganza <danverbraganza@gmail.com>
- Max Countryman
- Nick Chadwick
- Jonathan Drosdeck
- Jiri Machalek
- Steve Pulec
+8
View File
@@ -1,6 +1,14 @@
History
-------
0.11.0 (2012-03-14)
+++++++++++++++++++
* Private SSL Certificate support
* Remove select.poll from Gevent monkeypatching
* Remove redundant generator for chunked transfer encoding
* Fix: Response.ok raises Timeout Exception in safe_mode
0.10.8 (2012-03-09)
+++++++++++++++++++
+1 -1
View File
@@ -73,4 +73,4 @@ Contribute
#. Send a pull request and bug the maintainer until it gets merged and published. :) Make sure to add yourself to AUTHORS_.
.. _`the repository`: http://github.com/kennethreitz/requests
.. _AUTHORS: http://github.com/kennethreitz/requests/blob/master/AUTHORS
.. _AUTHORS: https://github.com/kennethreitz/requests/blob/develop/AUTHORS.rst
-3
View File
@@ -50,9 +50,6 @@ Requests is available installed as a Debian package! Debian Etch Ubuntu, since O
$ apt-get install python-requests
Unfortunately, the most recent version available is v0.5.0. If you're on the
Debian Python Package team, I'd love an update of that :)
Fedora and RedHat
-----------------
+26
View File
@@ -30,6 +30,32 @@ Let's get GitHub's public timeline ::
Now, we have a :class:`Response` object called ``r``. We can get all the
information we need from this.
Typically, you want to send some sort of data in the urls query string.
To do this, simply pass a dictionary to the `params` argument. Your
dictionary of data will automatically be encoded when the request is made::
>>> payload = {'key1': 'value1', 'key2': 'value2'}
>>> r = requests.get("http://httpbin.org/get", params=payload)
>>> print r.text
{
"origin": "179.13.100.4",
"args": {
"key2": "value2",
"key1": "value1"
},
"url": "http://httpbin.org/get",
"headers": {
"Connections": "keep-alive",
"Content-Length": "",
"Accept-Encoding": "identity, deflate, compress, gzip",
"Accept": "*/*",
"User-Agent": "python-requests/0.11.0",
"Host": httpbin.org",
"Content-Type": ""
},
}
Response Content
----------------
+2 -2
View File
@@ -15,8 +15,8 @@ requests
"""
__title__ = 'requests'
__version__ = '0.10.8'
__build__ = 0x001008
__version__ = '0.11.0'
__build__ = 0x001100
__author__ = 'Kenneth Reitz'
__license__ = 'ISC'
__copyright__ = 'Copyright 2012 Kenneth Reitz'
+8 -7
View File
@@ -33,6 +33,7 @@ def request(method, url, **kwargs):
:param config: (optional) A configuration dictionary.
:param verify: (optional) if ``True``, the SSL cert will be verified. A CA_BUNDLE path can also be provided.
:param prefetch: (optional) if ``True``, the response content will be immediately downloaded.
:param cert: (optional) if String, path to ssl client cert file (.pem). If Tuple, ('cert', 'key') pair.
"""
s = kwargs.pop('session') if 'session' in kwargs else sessions.session()
@@ -44,7 +45,7 @@ def get(url, **kwargs):
"""Sends a GET request. Returns :class:`Response` object.
:param url: URL for the new :class:`Request` object.
:param **kwargs: Optional arguments that ``request`` takes.
:param \*\*kwargs: Optional arguments that ``request`` takes.
"""
kwargs.setdefault('allow_redirects', True)
@@ -55,7 +56,7 @@ def options(url, **kwargs):
"""Sends a OPTIONS request. Returns :class:`Response` object.
:param url: URL for the new :class:`Request` object.
:param **kwargs: Optional arguments that ``request`` takes.
:param \*\*kwargs: Optional arguments that ``request`` takes.
"""
kwargs.setdefault('allow_redirects', True)
@@ -66,7 +67,7 @@ def head(url, **kwargs):
"""Sends a HEAD request. Returns :class:`Response` object.
:param url: URL for the new :class:`Request` object.
:param **kwargs: Optional arguments that ``request`` takes.
:param \*\*kwargs: Optional arguments that ``request`` takes.
"""
kwargs.setdefault('allow_redirects', False)
@@ -78,7 +79,7 @@ def post(url, data=None, **kwargs):
:param url: URL for the new :class:`Request` object.
:param data: (optional) Dictionary or bytes to send in the body of the :class:`Request`.
:param **kwargs: Optional arguments that ``request`` takes.
:param \*\*kwargs: Optional arguments that ``request`` takes.
"""
return request('post', url, data=data, **kwargs)
@@ -89,7 +90,7 @@ def put(url, data=None, **kwargs):
:param url: URL for the new :class:`Request` object.
:param data: (optional) Dictionary or bytes to send in the body of the :class:`Request`.
:param **kwargs: Optional arguments that ``request`` takes.
:param \*\*kwargs: Optional arguments that ``request`` takes.
"""
return request('put', url, data=data, **kwargs)
@@ -100,7 +101,7 @@ def patch(url, data=None, **kwargs):
:param url: URL for the new :class:`Request` object.
:param data: (optional) Dictionary or bytes to send in the body of the :class:`Request`.
:param **kwargs: Optional arguments that ``request`` takes.
:param \*\*kwargs: Optional arguments that ``request`` takes.
"""
return request('patch', url, data=data, **kwargs)
@@ -110,7 +111,7 @@ def delete(url, **kwargs):
"""Sends a DELETE request. Returns :class:`Response` object.
:param url: URL for the new :class:`Request` object.
:param **kwargs: Optional arguments that ``request`` takes.
:param \*\*kwargs: Optional arguments that ``request`` takes.
"""
return request('delete', url, **kwargs)
+1 -1
View File
@@ -17,7 +17,7 @@ except ImportError:
raise RuntimeError('Gevent is required for requests.async.')
# Monkey-patch.
curious_george.patch_all(thread=False)
curious_george.patch_all(thread=False, select=False)
from . import api
+1 -1
View File
@@ -11,7 +11,7 @@ import time
import hashlib
from base64 import b64encode
from .compat import urlparse, str, bytes
from .compat import urlparse, str
from .utils import randombytes, parse_dict_header
+22 -36
View File
@@ -63,7 +63,8 @@ class Request(object):
config=None,
_poolmanager=None,
verify=None,
session=None):
session=None,
cert=None):
#: Dictionary of configurations for this request.
self.config = dict(config or [])
@@ -143,6 +144,9 @@ class Request(object):
#: SSL Verification.
self.verify = verify
#: SSL Certificate
self.cert = cert
if headers:
headers = CaseInsensitiveDict(self.headers)
else:
@@ -267,7 +271,8 @@ class Request(object):
_poolmanager=self._poolmanager,
proxies=self.proxies,
verify=self.verify,
session=self.session
session=self.session,
cert=self.cert
)
request.send()
@@ -507,6 +512,13 @@ class Request(object):
conn.cert_reqs = 'CERT_NONE'
conn.ca_certs = None
if self.cert and self.verify:
if len(self.cert) == 2:
conn.cert_file = self.cert[0]
conn.key_file = self.cert[1]
else:
conn.cert_file = self.cert
if not self.sent or anyway:
if self.cookies:
@@ -648,7 +660,7 @@ class Response(object):
def ok(self):
try:
self.raise_for_status()
except HTTPError:
except RequestException:
return False
return True
@@ -671,39 +683,7 @@ class Response(object):
yield chunk
self._content_consumed = True
def generate_chunked():
resp = self.raw._original_response
fp = resp.fp
if resp.chunk_left is not None:
pending_bytes = resp.chunk_left
while pending_bytes:
chunk = fp.read(min(chunk_size, pending_bytes))
pending_bytes -= len(chunk)
yield chunk
fp.read(2) # throw away crlf
while 1:
#XXX correct line size? (httplib has 64kb, seems insane)
pending_bytes = fp.readline(40).strip()
if not len(pending_bytes):
# No content, like a HEAD request. Break out.
break
pending_bytes = int(pending_bytes, 16)
if pending_bytes == 0:
break
while pending_bytes:
chunk = fp.read(min(chunk_size, pending_bytes))
pending_bytes -= len(chunk)
yield chunk
fp.read(2) # throw away crlf
self._content_consumed = True
fp.close()
if getattr(getattr(self.raw, '_original_response', None), 'chunked', False):
gen = generate_chunked()
else:
gen = generate()
gen = stream_untransfer(gen, self)
gen = stream_untransfer(generate(), self)
if decode_unicode:
gen = stream_decode_response_unicode(gen, self)
@@ -788,6 +768,12 @@ class Response(object):
# Decode unicode from given encoding.
try:
content = str(self.content, encoding, errors='replace')
except LookupError:
# A LookupError is raised if the encoding was not found which could
# indicate a misspelling or similar mistake.
#
# So we try blindly encoding.
content = str(self.content, errors='replace')
except (UnicodeError, TypeError):
pass
+1 -1
View File
@@ -255,7 +255,7 @@ class CookieError(Exception):
#
_RFC2965Forbidden = "[]:{}="
_LegalChars = ( string.ascii_letters + string.digits +
"!#$%&'*+-.^_`|~_" + _RFC2965Forbidden )
"!#$%&'*+-.^_`|~_@" + _RFC2965Forbidden )
_Translator = {
'\000' : '\\000', '\001' : '\\001', '\002' : '\\002',
'\003' : '\\003', '\004' : '\\004', '\005' : '\\005',
+15 -10
View File
@@ -52,7 +52,7 @@ class Session(object):
__attrs__ = [
'headers', 'cookies', 'auth', 'timeout', 'proxies', 'hooks',
'params', 'config', 'verify']
'params', 'config', 'verify', 'cert']
def __init__(self,
@@ -65,7 +65,8 @@ class Session(object):
params=None,
config=None,
prefetch=False,
verify=True):
verify=True,
cert=None):
self.headers = headers or {}
self.cookies = cookies or {}
@@ -77,6 +78,7 @@ class Session(object):
self.config = config or {}
self.prefetch = prefetch
self.verify = verify
self.cert = cert
for (k, v) in list(defaults.items()):
self.config.setdefault(k, v)
@@ -119,7 +121,8 @@ class Session(object):
return_response=True,
config=None,
prefetch=False,
verify=None):
verify=None,
cert=None):
"""Constructs and sends a :class:`Request <Request>`.
Returns :class:`Response <Response>` object.
@@ -139,6 +142,7 @@ class Session(object):
:param config: (optional) A configuration dictionary.
:param prefetch: (optional) if ``True``, the response content will be immediately downloaded.
:param verify: (optional) if ``True``, the SSL cert will be verified. A CA_BUNDLE path can also be provided.
:param cert: (optional) if String, path to ssl client cert file (.pem). If Tuple, ('cert', 'key') pair.
"""
method = str(method).upper()
@@ -176,6 +180,7 @@ class Session(object):
proxies=proxies,
config=config,
verify=verify,
cert=cert,
_poolmanager=self.poolmanager
)
@@ -213,7 +218,7 @@ class Session(object):
"""Sends a GET request. Returns :class:`Response` object.
:param url: URL for the new :class:`Request` object.
:param **kwargs: Optional arguments that ``request`` takes.
:param \*\*kwargs: Optional arguments that ``request`` takes.
"""
kwargs.setdefault('allow_redirects', True)
@@ -224,7 +229,7 @@ class Session(object):
"""Sends a OPTIONS request. Returns :class:`Response` object.
:param url: URL for the new :class:`Request` object.
:param **kwargs: Optional arguments that ``request`` takes.
:param \*\*kwargs: Optional arguments that ``request`` takes.
"""
kwargs.setdefault('allow_redirects', True)
@@ -235,7 +240,7 @@ class Session(object):
"""Sends a HEAD request. Returns :class:`Response` object.
:param url: URL for the new :class:`Request` object.
:param **kwargs: Optional arguments that ``request`` takes.
:param \*\*kwargs: Optional arguments that ``request`` takes.
"""
kwargs.setdefault('allow_redirects', False)
@@ -247,7 +252,7 @@ class Session(object):
:param url: URL for the new :class:`Request` object.
:param data: (optional) Dictionary or bytes to send in the body of the :class:`Request`.
:param **kwargs: Optional arguments that ``request`` takes.
:param \*\*kwargs: Optional arguments that ``request`` takes.
"""
return self.request('post', url, data=data, **kwargs)
@@ -258,7 +263,7 @@ class Session(object):
:param url: URL for the new :class:`Request` object.
:param data: (optional) Dictionary or bytes to send in the body of the :class:`Request`.
:param **kwargs: Optional arguments that ``request`` takes.
:param \*\*kwargs: Optional arguments that ``request`` takes.
"""
return self.request('put', url, data=data, **kwargs)
@@ -269,7 +274,7 @@ class Session(object):
:param url: URL for the new :class:`Request` object.
:param data: (optional) Dictionary or bytes to send in the body of the :class:`Request`.
:param **kwargs: Optional arguments that ``request`` takes.
:param \*\*kwargs: Optional arguments that ``request`` takes.
"""
return self.request('patch', url, data=data, **kwargs)
@@ -279,7 +284,7 @@ class Session(object):
"""Sends a DELETE request. Returns :class:`Response` object.
:param url: URL for the new :class:`Request` object.
:param **kwargs: Optional arguments that ``request`` takes.
:param \*\*kwargs: Optional arguments that ``request`` takes.
"""
return self.request('delete', url, **kwargs)
+9 -1
View File
@@ -14,7 +14,6 @@ import codecs
import os
import random
import re
import traceback
import zlib
from netrc import netrc, NetrcParseError
@@ -26,6 +25,15 @@ from .compat import basestring, bytes, str
NETRC_FILES = ('.netrc', '_netrc')
def dict_to_sequence(d):
"""Returns an internal sequence dictionary update."""
if hasattr(d, 'items'):
d = d.items()
return d
def get_netrc_auth(url):
"""Returns the Requests tuple auth for a given url from netrc."""
Regular → Executable
+6
View File
@@ -8,6 +8,9 @@ sys.path.insert(0, os.path.abspath('..'))
import sys
import unittest
import select
has_poll = hasattr(select, "poll")
from requests import async
import envoy
@@ -57,6 +60,9 @@ class RequestsTestSuiteUsingAsyncApi(RequestsTestSuite):
async.map
async.send
def test_select_poll(self):
"""Test to make sure we don't overwrite the poll"""
self.assertEqual(hasattr(select, "poll"), has_poll)
if __name__ == '__main__':
unittest.main()