diff --git a/docs/conf.py b/docs/conf.py index 5c3eb6e0..8ea77310 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -48,9 +48,9 @@ copyright = u'2011, Kenneth Reitz' # built documents. # # The short X.Y version. -version = '0.2.0' +version = '0.3.2' # The full version, including alpha/beta/rc tags. -release = '0.2.0' +release = version # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/requests/core.py b/requests/core.py index 56c3d061..625d845f 100644 --- a/requests/core.py +++ b/requests/core.py @@ -14,6 +14,7 @@ from __future__ import absolute_import import urllib import urllib2 +import zlib from urllib2 import HTTPError from urlparse import urlparse @@ -24,15 +25,15 @@ from .packages.poster.streaminghttp import register_openers, get_handlers __title__ = 'requests' -__version__ = '0.3.1' -__build__ = 0x000301 +__version__ = '0.3.2' +__build__ = 0x000302 __author__ = 'Kenneth Reitz' __license__ = 'ISC' __copyright__ = 'Copyright 2011 Kenneth Reitz' __all__ = [ - 'Request', 'Response', 'request', 'get', 'head', 'post', 'put', 'delete', - 'auth_manager', 'AuthObject','RequestException', 'AuthenticationError', + 'Request', 'Response', 'request', 'get', 'head', 'post', 'put', 'delete', + 'auth_manager', 'AuthObject','RequestException', 'AuthenticationError', 'URLRequired', 'InvalidMethod', 'HTTPError' ] @@ -63,7 +64,7 @@ class Request(object): def __init__(self, url=None, headers=dict(), files=None, method=None, data=dict(), auth=None, cookiejar=None): - + self.url = url self.headers = headers self.files = files @@ -141,17 +142,23 @@ class Request(object): def _build_response(self, resp): """Build internal Response object from given response.""" - + self.response.status_code = getattr(resp, 'code', None) self.response.headers = getattr(resp.info(), 'dict', None) - self.response.url = getattr(resp, 'url', None) self.response.content = resp.read() + if self.response.headers.get('content-encoding', None) == 'gzip': + try: + self.response.content = zlib.decompress(self.response.content, 16+zlib.MAX_WBITS) + except zlib.error: + pass + + self.response.url = getattr(resp, 'url', None) @staticmethod def _build_url(url, data): """Build URLs.""" - + if urlparse(url).query: return '%s&%s' % (url, data) else: @@ -182,10 +189,10 @@ class Request(object): if self.data: self.files.update(self.data) - + datagen, headers = multipart_encode(self.files) req = _Request(self.url, data=datagen, headers=headers, method=self.method) - + else: req = _Request(self.url, data=self._enc_data, method=self.method) @@ -199,7 +206,7 @@ class Request(object): if self.cookiejar is not None: self.cookiejar.extract_cookies(resp, req) - + except urllib2.HTTPError, why: self._build_response(why) self.response.error = why @@ -216,9 +223,9 @@ class Request(object): return self.sent - def read(self): + def read(self, *args): return self.response.read() - + class Response(object): """The :class:`Request` object. All :class:`Request` objects contain a :class:`Request.response ` attribute, which is an instance of @@ -249,13 +256,13 @@ class Response(object): if self.error: raise self.error - def read(self): + def read(self, *args): return self.content class AuthManager(object): """Authentication Manager.""" - + def __new__(cls): singleton = cls.__dict__.get('__singleton__') if singleton is not None: @@ -277,8 +284,16 @@ class AuthManager(object): def add_auth(self, uri, auth): """Registers AuthObject to AuthManager.""" - + uri = self.reduce_uri(uri, False) + + # try to make it an AuthObject + if not isinstance(auth, AuthObject): + try: + auth = AuthObject(*auth) + except TypeError: + pass + self._auth[uri] = auth def add_password(self, realm, uri, user, passwd): @@ -286,9 +301,9 @@ class AuthManager(object): # uri could be a single URI or a sequence if isinstance(uri, basestring): uri = [uri] - + reduced_uri = tuple([self.reduce_uri(u, False) for u in uri]) - + if reduced_uri not in self.passwd: self.passwd[reduced_uri] = {} self.passwd[reduced_uri] = (user, passwd) @@ -305,8 +320,14 @@ class AuthManager(object): def get_auth(self, uri): - uri = self.reduce_uri(uri, False) - return self._auth.get(uri, None) + (in_domain, in_path) = self.reduce_uri(uri, False) + + for domain, path, authority in ( + (i[0][0], i[0][1], i[1]) for i in self._auth.iteritems() + ): + if in_domain == domain: + if path in in_path: + return authority def reduce_uri(self, uri, default_port=True): @@ -330,9 +351,10 @@ class AuthManager(object): }.get(scheme) if dport is not None: authority = "%s:%d" % (host, dport) + return authority, path - + def is_suburi(self, base, test): """Check if test is below base in a URI tree @@ -441,7 +463,7 @@ def get(url, params={}, headers={}, cookies=None, auth=None): :param cookies: (optional) CookieJar object to send with the :class:`Request`. :param auth: (optional) AuthObject to enable Basic HTTP Auth. """ - + return request('GET', url, params=params, headers=headers, cookies=cookies, auth=auth) diff --git a/setup.py b/setup.py index edf89f1d..b261718a 100644 --- a/setup.py +++ b/setup.py @@ -8,7 +8,7 @@ import requests from distutils.core import setup - + if sys.argv[-1] == "publish": os.system("python setup.py sdist upload") sys.exit() @@ -16,10 +16,11 @@ if sys.argv[-1] == "publish": if sys.argv[-1] == "test": os.system("python test_requests.py") sys.exit() - + required = [] -# if python > 2.6, require simplejson +if sys.version_info[:2] < (2,6): + required.append('simplejson') setup( name='requests', diff --git a/test_requests.py b/test_requests.py old mode 100644 new mode 100755 index c3759f31..9b3dae9c --- a/test_requests.py +++ b/test_requests.py @@ -30,7 +30,7 @@ class RequestsTestSuite(unittest.TestCase): def test_HTTP_200_OK_GET_WITH_PARAMS(self): heads = {'User-agent': 'Mozilla/5.0'} - + r = requests.get('http://www.google.com/search', params={'q': 'test'}, headers=heads) self.assertEqual(r.status_code, 200) @@ -47,7 +47,7 @@ class RequestsTestSuite(unittest.TestCase): r = requests.get('http://whatsmyua.com', headers=heads); self.assertTrue(heads['User-agent'] in r.content) - + def test_HTTP_200_OK_HEAD(self): r = requests.head('http://google.com') self.assertEqual(r.status_code, 200) @@ -71,9 +71,8 @@ class RequestsTestSuite(unittest.TestCase): def test_POSTBIN_GET_POST_FILES(self): bin = requests.post('http://www.postbin.org/') - print bin.url self.assertEqual(bin.status_code, 200) - + post = requests.post(bin.url, data={'some': 'data'}) self.assertEqual(post.status_code, 201) @@ -82,7 +81,7 @@ class RequestsTestSuite(unittest.TestCase): def test_POSTBIN_GET_POST_FILES_WITH_PARAMS(self): bin = requests.post('http://www.postbin.org/') - + self.assertEqual(bin.status_code, 200) post2 = requests.post(bin.url, files={'some': open('test_requests.py')}, data={'some': 'data'}) @@ -97,26 +96,26 @@ class RequestsTestSuite(unittest.TestCase): headers={'User-Agent': 'requests-tests'}) self.assertEqual(post2.status_code, 201) - + def test_nonzero_evaluation(self): r = requests.get('http://google.com/some-404-url') self.assertEqual(bool(r), False) - + r = requests.get('http://google.com/') self.assertEqual(bool(r), True) - + def test_request_ok_set(self): r = requests.get('http://google.com/some-404-url') self.assertEqual(r.ok, False) - + def test_status_raising(self): r = requests.get('http://google.com/some-404-url') self.assertRaises(requests.HTTPError, r.raise_for_status) - + r = requests.get('http://google.com/') self.assertFalse(r.error) r.raise_for_status() - + def test_cookie_jar(self): """ .. todo:: This really doesn't test to make sure the cookie is working @@ -127,7 +126,18 @@ class RequestsTestSuite(unittest.TestCase): requests.get('http://google.com', cookies=jar) self.assertTrue(jar) + def test_decompress_gzip(self): + r = requests.get('http://api.stackoverflow.com/1.1/users/495995/top-answer-tags') + r.content.decode('ascii') + + def test_autoauth(self): + + conv_auth = ('requeststest', 'requeststest') + requests.auth_manager.add_auth('convore.com', conv_auth) + + r = requests.get('https://convore.com/api/account/verify.json') + self.assertEquals(r.status_code, 200) if __name__ == '__main__': unittest.main()