diff --git a/HISTORY.rst b/HISTORY.rst index 41118bbe..6f15dc91 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -1,6 +1,14 @@ History ------- +0.2.2 (2011-02-14) +++++++++++++++++++ +* Still handles request in the event of an HTTPError. (Issue #2) +* Eventlet and Gevent Monkeypatch support. +* Cookie Support (Issue #1) + + + 0.2.1 (2011-02-14) ++++++++++++++++++ diff --git a/README.rst b/README.rst index b18557df..9b987ef8 100644 --- a/README.rst +++ b/README.rst @@ -56,27 +56,28 @@ API **Requests:** All request functions return a Response object (see below). + +If a {filename: fileobject} dictionary is passed in (files=...), a multipart_encode upload will be performed. +If CookieJar object is is passed in (cookies=...), the cookies will be sent with the request. GET Requests - >>> request.get(url, params={}, headers={} auth=None) + >>> request.get(url, params={}, headers={}, cookies=None, auth=None) HEAD Requests - >>> request.head(url, params={}, headers={} auth=None) + >>> request.head(url, params={}, headers={}, cookies=None, auth=None) PUT Requests - >>> request.put(url, data='', headers={}, files={}, auth=None) + >>> request.put(url, data='', headers={}, files={}, cookies=None, auth=None) - # If files dictionary ( {filename: fileobject, ...} ) is given, a multi-part upload is performed. POST Requests - >>> request.post(url, data={}, headers={}, files={}, auth=None) + >>> request.post(url, data={}, headers={}, files={}, cookies=None, auth=None) - # If files dictionary ( {filename: fileobject, ...} ) is given, a multi-part upload is performed. DELETE Requests - >>> request.delete(url, params={}, headers={}, auth=None) + >>> request.delete(url, params={}, headers={}, cookies=None, auth=None) diff --git a/requests/core.py b/requests/core.py index e46718dd..28d05053 100644 --- a/requests/core.py +++ b/requests/core.py @@ -13,6 +13,21 @@ import urllib import urllib2 + +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 @@ -59,7 +74,9 @@ class Request(object): self.params = {} self.data = {} self.response = Response() + self.auth = None + self.cookiejar = None self.sent = False @@ -76,7 +93,7 @@ class Request(object): def _checks(self): - """Deterministic checks for consistiency.""" + """Deterministic checks for consistency.""" if not self.url: raise URLRequired @@ -84,18 +101,28 @@ class Request(object): def _get_opener(self): """Creates appropriate opener object for urllib2.""" - - if self.auth: - # create a password manager - authr = urllib2.HTTPPasswordMgrWithDefaultRealm() + _handlers = [] - authr.add_password(None, self.url, self.auth.username, self.auth.password) - handler = urllib2.HTTPBasicAuthHandler(authr) - opener = urllib2.build_opener(handler) + if self.auth or self.cookiejar: - # use the opener to fetch a URL + if self.auth: + + authr = urllib2.HTTPPasswordMgrWithDefaultRealm() + + authr.add_password(None, self.url, self.auth.username, self.auth.password) + auth_handler = urllib2.HTTPBasicAuthHandler(authr) + + _handlers.append(auth_handler) + + if self.cookiejar: + + cookie_handler = urllib2.HTTPCookieProcessor(cookiejar) + _handlers.append(cookie_handler) + + opener = urllib2.build_opener(*_handlers) return opener.open + else: return urllib2.urlopen @@ -108,6 +135,7 @@ class Request(object): 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, @@ -255,12 +283,13 @@ class AuthObject(object): -def get(url, params={}, headers={}, auth=None): +def get(url, params={}, headers={}, cookies=None, auth=None): """Sends a GET 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 headers: (optional) Dictionary of HTTP Headers to sent 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 auth: (optional) AuthObject to enable Basic HTTP Auth. """ @@ -270,6 +299,7 @@ def get(url, params={}, headers={}, auth=None): r.url = url r.params = params r.headers = headers + r.cookiejar = cookies r.auth = _detect_auth(url, auth) r.send() @@ -277,12 +307,13 @@ def get(url, params={}, headers={}, auth=None): return r.response -def head(url, params={}, headers={}, auth=None): +def head(url, params={}, headers={}, cookies=None, auth=None): """Sends a HEAD 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 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. """ @@ -293,6 +324,7 @@ def head(url, params={}, headers={}, auth=None): # return response object r.params = params r.headers = headers + r.cookiejar = cookies r.auth = _detect_auth(url, auth) r.send() @@ -300,13 +332,14 @@ def head(url, params={}, headers={}, auth=None): return r.response -def post(url, data={}, headers={}, files=None, auth=None): +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 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. """ @@ -320,6 +353,7 @@ def post(url, data={}, headers={}, files=None, auth=None): r.files = files r.headers = headers + r.cookiejar = cookies r.auth = _detect_auth(url, auth) r.send() @@ -327,13 +361,14 @@ def post(url, data={}, headers={}, files=None, auth=None): return r.response -def put(url, data='', headers={}, files={}, auth=None): +def put(url, data='', 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 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. """ @@ -344,6 +379,7 @@ def put(url, data='', headers={}, files={}, auth=None): r.data = data r.files = files r.headers = headers + r.cookiejar = cookies r.auth = _detect_auth(url, auth) r.send() @@ -351,12 +387,13 @@ def put(url, data='', headers={}, files={}, auth=None): return r.response -def delete(url, params={}, headers={}, auth=None): +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 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. """ @@ -366,6 +403,7 @@ def delete(url, params={}, headers={}, auth=None): r.method = 'DELETE' r.headers = headers + r.cookiejar = cookies r.auth = _detect_auth(url, auth) r.send()