Remove the eventles code, this should live in requests.async or something so the...
authordigitalxero <none@none>
Sat, 19 Feb 2011 15:51:54 +0000 (10:51 -0500)
committerdigitalxero <none@none>
Sat, 19 Feb 2011 15:51:54 +0000 (10:51 -0500)
Clean up the code to get rid of the unnecessary AuthObject class
Cleanup the send method
Cleanup the convenience methods by adding a request method that they all use.

requests/core.py
test_requests.py

index 9292a9a..e511b84 100644 (file)
 from __future__ import absolute_import
 import urllib
 import urllib2
-
 from urllib2 import HTTPError
 
-try:
-    import eventlet
-    eventlet.monkey_patch()
-except ImportError:
-    pass
-
-if not 'eventlet' in locals():
-    try:
-        from gevent import monkey
-        monkey.patch_all()
-    except ImportError:
-        pass
-
 from .packages.poster.encode import multipart_encode
 from .packages.poster.streaminghttp import register_openers
 
-
+__all__ = ['Request', 'Response', 'request', 'get', 'head', 'post', 'put', 'delete', 'add_autoauth', 'AUTOAUTHS',
+           'RequestException', 'AuthenticationError', 'URLRequired', 'InvalidMethod', 'HTTPError']
 __title__ = 'requests'
 __version__ = '0.2.4'
 __build__ = 0x000204
@@ -43,13 +30,11 @@ __copyright__ = 'Copyright 2011 Kenneth Reitz'
 
 AUTOAUTHS = []
 
-
-
 class _Request(urllib2.Request):
     """Hidden wrapper around the urllib2.Request object. Allows for manual
     setting of HTTP methods.
     """
-    
+
     def __init__(self, url, data=None, headers={}, origin_req_host=None,
                  unverifiable=False, method=None):
         urllib2.Request.__init__(self, url, data, headers, origin_req_host, unverifiable)
@@ -66,61 +51,59 @@ class Request(object):
     """The :class:`Request` object. It carries out all functionality of
     Requests. Recommended interface is with the Requests functions.
     """
-    
+
     _METHODS = ('GET', 'HEAD', 'PUT', 'POST', 'DELETE')
-    
+
     def __init__(self, url=None, headers=dict(), files=None, method=None,
-                 params=dict(), data=dict(), auth=None, cookiejar=None):
+                 data=dict(), auth=None, cookiejar=None):
         self.url = url
         self.headers = headers
         self.files = files
         self.method = method
-        self.params = params
-        self.data = data
+
+        # url encode data if it's a dict
+        if isinstance(data, dict):
+            self.data = urllib.urlencode(data)
+        else:
+            self.data = data
+
         self.response = Response()
-        
+
         self.auth = auth
         self.cookiejar = cookiejar
         self.sent = False
-        
-        
+
     def __repr__(self):
         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."""
 
         if not self.url:
             raise URLRequired
 
-        
     def _get_opener(self):
         """Creates appropriate opener object for urllib2."""
 
         _handlers = []
 
         if self.auth or self.cookiejar:
-
             if self.auth:
-
                 authr = urllib2.HTTPPasswordMgrWithDefaultRealm()
 
-                authr.add_password(None, self.url, self.auth.username, self.auth.password)
+                authr.add_password(None, self.url, self.auth[0], self.auth[1])
                 auth_handler = urllib2.HTTPBasicAuthHandler(authr)
 
                 _handlers.append(auth_handler)
 
             if self.cookiejar:
-
                 cookie_handler = urllib2.HTTPCookieProcessor(cookiejar)
                 _handlers.append(cookie_handler)
 
@@ -133,13 +116,13 @@ class Request(object):
 
     def _build_response(self, resp):
         """Build internal Response object from given response."""
-        
+
         self.response.status_code = resp.code
         self.response.headers = resp.info().dict
         self.response.content = resp.read()
         self.response.url = resp.url
 
-    
+
     def send(self, anyway=False):
         """Sends the request. Returns True of successful, false if not.
         If there was an HTTPError during transmission,
@@ -150,106 +133,44 @@ class Request(object):
         :param anyway: If True, request will be sent, even if it has
         already been sent.
         """
-
         self._checks()
-
         success = False
 
-
         if self.method in ('GET', 'HEAD', 'DELETE'):
-            if (not self.sent) or anyway:
-
-                # url encode GET params if it's a dict
-                if isinstance(self.params, dict):
-                    params = urllib.urlencode(self.params)
-                else:
-                    params = self.params
+            req = _Request(("%s?%s" % (self.url, self.data)), method=self.method)
+        else:
+            if self.files:
+                register_openers()
+                datagen, headers = multipart_encode(self.files)
+                req = _Request(self.url, data=datagen, headers=headers, method=self.method)
+            else:
+                req = _Request(self.url, method=self.method)
 
-                req = _Request(("%s?%s" % (self.url, params)), method=self.method)
+            if self.data:
+                req.data = self.data
 
-                if self.headers:
-                    req.headers = self.headers
+        if self.headers:
+            req.headers = self.headers
 
+        if not self.sent or anyway:
+            try:
                 opener = self._get_opener()
+                resp =  opener(req)
+            except urllib2.HTTPError, why:
+                self._build_response(why)
+                self.response.error = why
+            else:
+                self._build_response(resp)
+                self.response.ok = True
+                self.response.cached = False
+        else:
+            self.response.cached = True
 
-                try:
-                    resp = opener(req)
-                    self._build_response(resp)
-                    self.response.ok = True
-
-                except urllib2.HTTPError, why:
-                    self._build_response(why)
-                    self.response.error = why
-
-
-        elif self.method == 'PUT':
-            if (not self.sent) or anyway:
-
-                if self.files:
-                    register_openers()
-                    datagen, headers = multipart_encode(self.files)
-                    req = _Request(self.url, data=datagen, headers=headers, method='PUT')
-
-                    if self.headers:
-                        req.headers.update(self.headers)
-
-                else:
-
-                    req = _Request(self.url, method='PUT')
-
-                    if self.headers:
-                        req.headers = self.headers
-
-                    req.data = self.data
-
-                try:
-                    opener = self._get_opener()
-                    resp =  opener(req)
-
-                    self._build_response(resp)
-                    self.response.ok = True
-
-                except urllib2.HTTPError, why:
-                    self._build_response(why)
-                    self.response.error = why
-
-
-        elif self.method == 'POST':
-            if (not self.sent) or anyway:
-
-                if self.files:
-                    register_openers()
-                    datagen, headers = multipart_encode(self.files)
-                    req = _Request(self.url, data=datagen, headers=headers, method='POST')
-
-                    if self.headers:
-                        req.headers.update(self.headers)
-                
-                else:
-                    req = _Request(self.url, method='POST')
-                    req.headers = self.headers
-
-                    # url encode form data if it's a dict
-                    if isinstance(self.data, dict):
-                        req.data = urllib.urlencode(self.data)
-                    else:
-                        req.data = self.data
-
-                try:
-                    opener = self._get_opener()
-                    resp =  opener(req)
-
-                    self._build_response(resp)
-                    self.response.ok = True
 
-                except urllib2.HTTPError, why:
-                    self._build_response(why)
-                    self.response.error = why
-        
         self.sent = self.response.ok
-        
+
         return self.sent
-        
+
 
 class Response(object):
     """The :class:`Request` object. All :class:`Request` objects contain a
@@ -264,36 +185,41 @@ class Response(object):
         self.url = None
         self.ok = False
         self.error = None
-        
+        self.cached = False
+
     def __repr__(self):
         return '<Response [%s]>' % (self.status_code)
-        
+
     def __nonzero__(self):
         """Returns true if status_code is 'OK'."""
         return not self.error
-        
+
     def raise_for_status(self):
         """Raises stored HTTPError if one exists."""
         if self.error:
             raise self.error
 
 
-    
-class AuthObject(object):
-    """The :class:`AuthObject` is a simple HTTP Authentication token. When
-    given to a Requests function, it enables Basic HTTP Authentication for that
-    Request. You can also enable Authorization for domain realms with AutoAuth.
-    See AutoAuth for more details.
-    
-    :param username: Username to authenticate with.
-    :param password: Password for given username.
+def request(method, url, **kwargs):
+    """Sends a `method` request. Returns :class:`Response` object.
+
+    :param method: method for the new :class:`Request` object.
+    :param url: URL for the new :class:`Request` object.
+    :param params: (optional) Dictionary of GET/HEAD/DELETE Parameters to send with the :class:`Request`.
+    :param data: (optional) Bytes/Dictionary of PUT/POST Data to send with the :class:`Request`.
+    :param headers: (optional) Dictionary of HTTP Headers to send with the :class:`Request`.
+    :param cookies: (optional) CookieJar object to send with the :class:`Request`.
+    :param files: (optional) Dictionary of 'filename': file-like-objects for multipart encoding upload.
+    :param auth: (optional) AuthObject to enable Basic HTTP Auth.
     """
-    
-    def __init__(self, username, password):
-        self.username = username
-        self.password = password
+    data = kwargs.pop('data', {}) or kwargs.pop('params', {})
 
+    r = Request(method=method, url=url, data=data, headers=kwargs.pop('headers', {}),
+                cookiejar=kwargs.pop('cookies', None), files=kwargs.pop('files', None),
+                auth=_detect_auth(url, kwargs.pop('auth', None)))
+    r.send()
 
+    return r.response
 
 def get(url, params={}, headers={}, cookies=None, auth=None):
     """Sends a GET request. Returns :class:`Response` object.
@@ -304,12 +230,9 @@ 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.
     """
-    
-    r = Request(method='GET', url=url, params=params, headers=headers,
-                cookiejar=cookies, auth=_detect_auth(url, auth))
-    r.send()
-    
-    return r.response
+
+    return request('GET', url, params=params, headers=headers, cookiejar=cookies,
+                    auth=_detect_auth(url, auth))
 
 
 def head(url, params={}, headers={}, cookies=None, auth=None):
@@ -321,64 +244,53 @@ def head(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.
     """
-    r = Request(method='HEAD', url=url, params=params, headers=headers,
-                cookiejar=cookies, auth=_detect_auth(url, auth))
-    r.send()
-    
-    return r.response
+
+    return request('HEAD', url, params=params, headers=headers, cookiejar=cookies,
+                    auth=_detect_auth(url, auth))
 
 
 def post(url, data={}, headers={}, files=None, cookies=None, auth=None):
     """Sends a POST request. Returns :class:`Response` object.
 
     :param url: URL for the new :class:`Request` object.
-    :param data: (optional) Dictionary of POST Data to send with the :class:`Request`.
+    :param data: (optional) Dictionary of POST data to send with the :class:`Request`.
     :param headers: (optional) Dictionary of HTTP Headers to sent with the :class:`Request`.
     :param files: (optional) Dictionary of 'filename': file-like-objects for multipart encoding upload.
     :param cookies: (optional) CookieJar object to send with the :class:`Request`.
     :param auth: (optional) AuthObject to enable Basic HTTP Auth.
     """
-    
-    r = Request(method='POST', url=url, data=data, headers=headers,
-                files=files, cookiejar=cookies, auth=_detect_auth(url, auth))
-    r.send()
-    
-    return r.response
-    
-    
-def put(url, data='', headers={}, files={}, cookies=None, auth=None):
+
+    return request('POST', url, data=data, headers=headers, files=files, cookiejar=cookies,
+                    auth=_detect_auth(url, auth))
+
+
+def put(url, data=b'', headers={}, files={}, cookies=None, auth=None):
     """Sends a PUT request. Returns :class:`Response` object.
 
     :param url: URL for the new :class:`Request` object.
-    :param data: (optional) Bytes of PUT Data to send with the :class:`Request`.
+    :param params: (optional) Bytes of PUT Data to send with the :class:`Request`.
     :param headers: (optional) Dictionary of HTTP Headers to sent with the :class:`Request`.
     :param files: (optional) Dictionary of 'filename': file-like-objects for multipart encoding upload.
     :param cookies: (optional) CookieJar object to send with the :class:`Request`.
     :param auth: (optional) AuthObject to enable Basic HTTP Auth.
     """
 
-    r = Request(method='PUT', url=url, data=data, headers=headers, files=files,
-                cookiejar=cookies, auth=_detect_auth(url, auth))
-    r.send()
-    
-    return r.response
+    return request('PUT', url, data=data, headers=headers, files=files, cookiejar=cookies,
+                    auth=_detect_auth(url, auth))
+
 
-    
 def delete(url, params={}, headers={}, cookies=None, auth=None):
     """Sends a DELETE request. Returns :class:`Response` object.
 
     :param url: URL for the new :class:`Request` object.
-    :param params: (optional) Dictionary of GET Parameters to send with the :class:`Request`.
+    :param params: (optional) Dictionary of DELETE Parameters to send with the :class:`Request`.
     :param headers: (optional) Dictionary of HTTP Headers to sent with the :class:`Request`.
     :param cookies: (optional) CookieJar object to send with the :class:`Request`.
     :param auth: (optional) AuthObject to enable Basic HTTP Auth.
     """
-    
-    r = Request(method='DELETE', url=url, params=params, headers=headers,
-                cookiejar=cookies, auth=_detect_auth(url, auth))
-    r.send()
-    
-    return r.response
+
+    return request('DELETE', url, params=params, headers=headers, cookiejar=cookies,
+                    auth=_detect_auth(url, auth))
 
 
 def add_autoauth(url, authobject):
@@ -398,7 +310,7 @@ def add_autoauth(url, authobject):
     """
 
     global AUTOAUTHS
-    
+
     AUTOAUTHS.append((url, authobject))
 
 
@@ -409,14 +321,14 @@ def _detect_auth(url, auth):
 
     return _get_autoauth(url) if not auth else auth
 
-    
+
 def _get_autoauth(url):
     """Returns registered AuthObject for given url if available."""
-    
+
     for (autoauth_url, auth) in AUTOAUTHS:
-        if autoauth_url in url: 
+        if autoauth_url in url:
             return auth
-            
+
     return None
 
 
@@ -426,9 +338,9 @@ class RequestException(Exception):
 
 class AuthenticationError(RequestException):
     """The authentication credentials provided were invalid."""
-    
+
 class URLRequired(RequestException):
     """A valid URL is required to make a request."""
-    
+
 class InvalidMethod(RequestException):
     """An inappropriate method was attempted."""
index e365c6e..7ea6798 100644 (file)
@@ -8,46 +8,40 @@ import requests
 
 class RequestsTestSuite(unittest.TestCase):
     """Requests test cases."""
-    
+
     def setUp(self):
         pass
 
     def tearDown(self):
         """Teardown."""
         pass
-        
+
     def test_invalid_url(self):
         self.assertRaises(ValueError, requests.get, 'hiwpefhipowhefopw')
 
-
     def test_HTTP_200_OK_GET(self):
         r = requests.get('http://google.com')
         self.assertEqual(r.status_code, 200)
 
-
     def test_HTTPS_200_OK_GET(self):
         r = requests.get('https://google.com')
         self.assertEqual(r.status_code, 200)
 
-
     def test_HTTP_200_OK_HEAD(self):
         r = requests.head('http://google.com')
         self.assertEqual(r.status_code, 200)
 
-
     def test_HTTPS_200_OK_HEAD(self):
         r = requests.head('https://google.com')
         self.assertEqual(r.status_code, 200)
 
-
     def test_AUTH_HTTPS_200_OK_GET(self):
-        auth = requests.AuthObject('requeststest', 'requeststest')
+        auth = ('requeststest', 'requeststest')
         url = 'https://convore.com/api/account/verify.json'
         r = requests.get(url, auth=auth)
 
         self.assertEqual(r.status_code, 200)
 
-
         requests.add_autoauth(url, auth)
 
         r = requests.get(url)
@@ -56,33 +50,27 @@ class RequestsTestSuite(unittest.TestCase):
         # reset auto authentication
         requests.AUTOAUTHS = []
 
-
-
     def test_POSTBIN_GET_POST_FILES(self):
-
-        bin = requests.post('http://www.postbin.org/')
+        bin = requests.get('http://www.postbin.org/')
         self.assertEqual(bin.status_code, 200)
 
         post = requests.post(bin.url, data={'some': 'data'})
-        self.assertEqual(post.status_code, 201)
+        self.assertEqual(post.status_code, 200)
 
         post2 = requests.post(bin.url, files={'some': open('test_requests.py')})
-        self.assertEqual(post2.status_code, 201)
-
+        self.assertEqual(post2.status_code, 200)
 
     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)