From 23d5761bd4676c6bcbe99d4da27b190837330bb7 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 2 Apr 2011 18:22:05 -0400 Subject: [PATCH 1/7] accept any extra args to r.read() --- requests/core.py | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/requests/core.py b/requests/core.py index 56c3d061..2aa0926a 100644 --- a/requests/core.py +++ b/requests/core.py @@ -31,8 +31,8 @@ __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 +63,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,7 +141,7 @@ 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) @@ -151,7 +151,7 @@ class Request(object): @staticmethod def _build_url(url, data): """Build URLs.""" - + if urlparse(url).query: return '%s&%s' % (url, data) else: @@ -182,10 +182,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 +199,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 +216,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 +249,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,7 +277,7 @@ class AuthManager(object): def add_auth(self, uri, auth): """Registers AuthObject to AuthManager.""" - + uri = self.reduce_uri(uri, False) self._auth[uri] = auth @@ -286,9 +286,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) @@ -332,7 +332,7 @@ class AuthManager(object): 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 +441,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) From 7a62b10ff2fb5091d77aaf63d1ab091713ead332 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Thu, 14 Apr 2011 19:44:29 -0400 Subject: [PATCH 2/7] Automatically decompress gzipped responses if content-type is set. fixes #19 --- requests/core.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/requests/core.py b/requests/core.py index 2aa0926a..4ec68242 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 @@ -144,9 +145,15 @@ class Request(object): 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): From 1359094cc8a46732c146486b3feb0d6fa09ca7f0 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Thu, 14 Apr 2011 19:46:35 -0400 Subject: [PATCH 3/7] test for gzip decompress --- test_requests.py | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/test_requests.py b/test_requests.py index c3759f31..edcb384b 100644 --- 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) @@ -73,7 +73,7 @@ class RequestsTestSuite(unittest.TestCase): 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 +82,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 +97,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 +127,10 @@ 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') if __name__ == '__main__': unittest.main() From 2814664e91d9a7516f0f5f156fb482b9109a8b5b Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Fri, 15 Apr 2011 17:18:58 -0400 Subject: [PATCH 4/7] Fixes #20. --- requests/core.py | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/requests/core.py b/requests/core.py index 4ec68242..2a4cc09b 100644 --- a/requests/core.py +++ b/requests/core.py @@ -286,6 +286,14 @@ class AuthManager(object): """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): @@ -312,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): @@ -337,6 +351,7 @@ class AuthManager(object): }.get(scheme) if dport is not None: authority = "%s:%d" % (host, dport) + return authority, path From f494cd9c7283f9f920d04a59ed47efd5ae0c284a Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Fri, 15 Apr 2011 17:24:03 -0400 Subject: [PATCH 5/7] add autoauth tuple http basic test --- test_requests.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) mode change 100644 => 100755 test_requests.py diff --git a/test_requests.py b/test_requests.py old mode 100644 new mode 100755 index edcb384b..9b3dae9c --- a/test_requests.py +++ b/test_requests.py @@ -71,7 +71,6 @@ 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'}) @@ -132,5 +131,13 @@ class RequestsTestSuite(unittest.TestCase): 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() From 6e14d4704d87f572ab3257956bf7f32b0e6dab79 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Fri, 15 Apr 2011 17:26:51 -0400 Subject: [PATCH 6/7] version bump --- docs/conf.py | 4 ++-- requests/core.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) 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 2a4cc09b..625d845f 100644 --- a/requests/core.py +++ b/requests/core.py @@ -25,8 +25,8 @@ 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' From b8b87d416e5e76b5aab322bd38f0b1cfb9218d01 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Fri, 15 Apr 2011 17:27:02 -0400 Subject: [PATCH 7/7] install simplejson if python < 2.6 --- setup.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) 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',