Merge branch 'develop'

This commit is contained in:
Kenneth Reitz
2011-08-20 18:26:04 -04:00
10 changed files with 100 additions and 34 deletions
+4
View File
@@ -35,3 +35,7 @@ Patches and Suggestions
- Jens Diemer
- Alex <@alopatin>
- Tom Hogans <tomhsx@gmail.com>
- Armin Ronacher
- Shrikant Sharat Kandula
- Mikko Ohtamaa
- Den Shabalin
+40
View File
@@ -0,0 +1,40 @@
Requests is written and maintained by Kenneth Reitz and
various contributors:
Development Lead
````````````````
- Kenneth Reitz <me@kennethreitz.com>
Patches and Suggestions
```````````````````````
- Various Pocoo Members
- Chris Adams
- Flavio Percoco Premoli
- Dj Gilcrease
- Justin Murphy
- Rob Madole
- Aram Dulyan
- Johannes Gorset
- 村山めがね (Megane Murayama)
- James Rowe
- Daniel Schauenberg
- Zbigniew Siciarz
- Daniele Tricoli 'Eriol'
- Richard Boulton
- Miguel Olivares <miguel@moliware.com>
- Alberto Paro
- Jérémy Bethmont
- 潘旭 (Xu Pan)
- Tamás Gulácsi
- Rubén Abad
- Peter Manser
- Jeremy Selie
<<<<<<< HEAD
- Jens Diemer
- Alex <@alopatin>
=======
- Tom Hogans <tomhsx@gmail.com>
>>>>>>> 0ed641a26ec2200de00e4bbf3d170c767375351e
+11
View File
@@ -2,6 +2,17 @@ History
-------
0.6.1 (2011-08-20)
++++++++++++++++++
* Enhanced status codes experience ``\o/``
* Set a maximum number of redirects (``settings.max_redirects``)
* Full Unicode URL support
* Support for protocol-less redirects.
* Allow for arbitrary request types.
* Bugfixes
0.6.0 (2011-08-17)
++++++++++++++++++
-6
View File
@@ -100,11 +100,5 @@ Contribute
If you'd like to contribute, simply fork `the repository`_, commit your changes to the **develop** branch (or branch off of it), and send a pull request. Make sure you add yourself to AUTHORS_.
Roadmap
-------
- Sphinx Documentation
.. _`the repository`: http://github.com/kennethreitz/requests
.. _AUTHORS: http://github.com/kennethreitz/requests/blob/master/AUTHORS
+1 -1
View File
@@ -34,7 +34,7 @@ Sessions can also be used to provide default data to the request methods::
with requests.session(auth=auth, headers=headers) as c:
# both 'x-test' and 'x-test2' are sent
c.get('http://httpbin.org/headers', header={'x-test2', 'true'})
c.get('http://httpbin.org/headers', headers={'x-test2': 'true'})
.. admonition:: Global Settings
+1
View File
@@ -61,6 +61,7 @@ settings.accept_gzip = True
settings.proxies = None
settings.verbose = None
settings.timeout = None
settings.max_redirects = 30
#: Use socket.setdefaulttimeout() as fallback?
settings.timeout_fallback = True
+2 -2
View File
@@ -12,8 +12,8 @@ This module implements the main Requests system.
"""
__title__ = 'requests'
__version__ = '0.6.0'
__build__ = 0x000600
__version__ = '0.6.1'
__build__ = 0x000601
__author__ = 'Kenneth Reitz'
__license__ = 'ISC'
__copyright__ = 'Copyright 2011 Kenneth Reitz'
+3
View File
@@ -21,3 +21,6 @@ class URLRequired(RequestException):
class InvalidMethod(RequestException):
"""An inappropriate method was attempted."""
class TooManyRedirects(RequestException):
"""Too many redirects."""
+34 -21
View File
@@ -21,10 +21,12 @@ from .structures import CaseInsensitiveDict
from .packages.poster.encode import multipart_encode
from .packages.poster.streaminghttp import register_openers, get_handlers
from .utils import dict_from_cookiejar
from .exceptions import RequestException, AuthenticationError, Timeout, URLRequired, InvalidMethod
from .exceptions import RequestException, AuthenticationError, Timeout, URLRequired, InvalidMethod, TooManyRedirects
from .status_codes import codes
REDIRECT_STATI = (301, 302, 303, 307)
REDIRECT_STATI = (codes.moved, codes.found, codes.other, codes.temporary_moved)
class Request(object):
@@ -32,8 +34,6 @@ class Request(object):
Requests. Recommended interface is with the Requests functions.
"""
_METHODS = ('GET', 'HEAD', 'PUT', 'POST', 'DELETE', 'PATCH')
def __init__(self,
url=None, headers=dict(), files=None, method=None, data=dict(),
params=dict(), auth=None, cookiejar=None, timeout=None, redirect=False,
@@ -116,14 +116,6 @@ class Request(object):
return '<Request [%s]>' % (self.method)
def __setattr__(self, name, value):
if (name == 'method') and (value):
if not value in self._METHODS:
raise InvalidMethod()
object.__setattr__(self, name, value)
def _checks(self):
"""Deterministic checks for consistency."""
@@ -184,7 +176,8 @@ class Request(object):
try:
response.headers = CaseInsensitiveDict(getattr(resp.info(), 'dict', None))
response.read = resp.read
response.close = resp.close
response._resp = resp
response._close = resp.close
if self.cookiejar:
@@ -211,20 +204,31 @@ class Request(object):
while (
('location' in r.headers) and
((self.method in ('GET', 'HEAD')) or
(r.status_code is 303) or
(r.status_code is codes.see_other) or
(self.allow_redirects))
):
r.close()
if not len(history) < settings.max_redirects:
raise TooManyRedirects()
history.append(r)
url = r.headers['location']
# Handle redirection without scheme (see: RFC 1808 Section 4)
if url.startswith('//'):
parsed_rurl = urlparse(r.url)
url = '%s:%s' % (parsed_rurl.scheme, url)
# Facilitate non-RFC2616-compliant 'location' headers
# (e.g. '/path/to/resource' instead of 'http://domain.tld/path/to/resource')
url = urljoin(r.url, url)
if not urlparse(url).netloc:
url = urljoin(r.url, urllib.quote(urllib.unquote(url)))
# http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.4
if r.status_code is 303:
if r.status_code is codes.see_other:
method = 'GET'
else:
method = self.method
@@ -269,10 +273,13 @@ class Request(object):
def _build_url(self):
"""Build the actual URL to use."""
# Support for unicode domain names.
parsed_url = list(urlparse(self.url))
parsed_url[1] = parsed_url[1].encode('idna')
self.url = urlunparse(parsed_url)
# Support for unicode domain names and paths.
scheme, netloc, path, params, query, fragment = urlparse(self.url)
netloc = netloc.encode('idna')
if isinstance(path, unicode):
path = path.encode('utf-8')
path = urllib.quote(urllib.unquote(path))
self.url = str(urlunparse([ scheme, netloc, path, params, query, fragment ]))
if self._enc_params:
if urlparse(self.url).query:
@@ -426,7 +433,8 @@ class Response(object):
except zlib.error:
pass
return self._content
else:
raise AttributeError
def raise_for_status(self):
"""Raises stored :class:`HTTPError` or :class:`URLError`, if one occured."""
@@ -434,6 +442,11 @@ class Response(object):
raise self.error
def close(self):
if self._resp.fp is not None and hasattr(self._resp.fp, '_sock'):
self._resp.fp._sock.recv = None
self._close()
class AuthManager(object):
"""Requests Authentication Manager."""
+4 -4
View File
@@ -22,9 +22,9 @@ _codes = {
# Redirection.
300: ('multiple_choices',),
301: ('moved_permanently', 'moved'),
301: ('moved_permanently', 'moved', '\\o-'),
302: ('found',),
302: ('see_other', 'other'),
303: ('see_other', 'other'),
304: ('not_modified',),
305: ('use_proxy',),
306: ('switch_proxy',),
@@ -36,7 +36,7 @@ _codes = {
401: ('unauthorized',),
402: ('payment_required', 'payment'),
403: ('forbidden',),
404: ('not_found',),
404: ('not_found', '-o-'),
405: ('method_not_allowed', 'not_allowed'),
406: ('not_acceptable',),
407: ('proxy_authentication_required', 'proxy_auth', 'proxy_authentication'),
@@ -62,7 +62,7 @@ _codes = {
499: ('client_closed_request',),
# Server Error.
500: ('internal_server_error', 'server_error'),
500: ('internal_server_error', 'server_error', '/o\\'),
501: ('not_implemented',),
502: ('bad_gateway',),
503: ('service_unavailable', 'unavailable'),