From d72d1162142d1bf8b1b5711c664fbbd674f349d1 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sat, 22 Oct 2011 18:10:18 -0400 Subject: [PATCH] Move request and get to session --- requests/api.py | 72 +++--------------------------- requests/sessions.py | 123 +++++++++++++++++++++++++++++++++++---------------- 2 files changed, 92 insertions(+), 103 deletions(-) diff --git a/requests/api.py b/requests/api.py index 41240f0..b737cfe 100644 --- a/requests/api.py +++ b/requests/api.py @@ -16,84 +16,24 @@ from .models import Request, Response, AuthObject from .status_codes import codes from .hooks import dispatch_hook from .utils import cookiejar_from_dict, header_expand - +from .sessions import session __all__ = ('request', 'get', 'head', 'post', 'patch', 'put', 'delete') + def request(method, url, params=None, data=None, headers=None, cookies=None, files=None, auth=None, timeout=None, allow_redirects=False, proxies=None, hooks=None, return_response=True): - """Constructs and sends a :class:`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 or bytes to be sent in the query string for the :class:`Request`. - :param data: (optional) Dictionary or bytes to send in the body of the :class:`Request`. - :param headers: (optional) Dictionary of HTTP Headers to send with the :class:`Request`. - :param cookies: (optional) Dict or 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. - :param timeout: (optional) Float describing the timeout of the request. - :param allow_redirects: (optional) Boolean. Set to True if POST/PUT/DELETE redirect following is allowed. - :param proxies: (optional) Dictionary mapping protocol to the URL of the proxy. - :param return_response: (optional) If False, an un-sent Request object will returned. - """ - - method = str(method).upper() - - if cookies is None: - cookies = {} - - cookies = cookiejar_from_dict(cookies) - - # Expand header values - if headers: - for k, v in headers.items() or {}: - headers[k] = header_expand(v) - - args = dict( - method = method, - url = url, - data = data, - params = params, - headers = headers, - cookiejar = cookies, - files = files, - auth = auth, - hooks = hooks, - timeout = timeout or config.settings.timeout, - allow_redirects = allow_redirects, - proxies = proxies or config.settings.proxies, + s = session() + return s.request( + method, url, params, data, headers, cookies, files, auth, + timeout, allow_redirects, proxies, hooks, return_response ) - # Arguments manipulation hook. - args = dispatch_hook('args', hooks, args) - - r = Request(**args) - - # Pre-request hook. - r = dispatch_hook('pre_request', hooks, r) - - # Don't send if asked nicely. - if not return_response: - return r - - # Send the HTTP Request. - r.send() - - # Post-request hook. - r = dispatch_hook('post_request', hooks, r) - - # Response manipulation hook. - r.response = dispatch_hook('response', hooks, r.response) - - return r.response def get(url, **kwargs): - """Sends a GET request. Returns :class:`Response` object. :param url: URL for the new :class:`Request` object. diff --git a/requests/sessions.py b/requests/sessions.py index 64ef7b2..0dc5e9d 100644 --- a/requests/sessions.py +++ b/requests/sessions.py @@ -11,9 +11,10 @@ requests (cookies, auth, proxies). import cookielib -from . import api -from .utils import add_dict_to_cookiejar - +from . import config +from .models import Request +from .hooks import dispatch_hook +from .utils import add_dict_to_cookiejar, cookiejar_from_dict, header_expand def merge_kwargs(local_kwarg, default_kwarg): @@ -25,6 +26,9 @@ def merge_kwargs(local_kwarg, default_kwarg): if default_kwarg is None: return local_kwarg + if isinstance(local_kwarg, basestring): + return local_kwarg + if local_kwarg is None: return default_kwarg @@ -32,8 +36,6 @@ def merge_kwargs(local_kwarg, default_kwarg): if not hasattr(default_kwarg, 'items'): return local_kwarg - - # Update new values. kwargs = default_kwarg.copy() kwargs.update(local_kwarg) @@ -73,7 +75,7 @@ class Session(object): self.cookies = cookielib.FileCookieJar() # Map and wrap requests.api methods - self._map_api_methods() + # self._map_api_methods() def __repr__(self): @@ -85,48 +87,95 @@ class Session(object): def __exit__(self, *args): pass - def _map_api_methods(self): - """Reads each available method from requests.api and decorates - them with a wrapper, which inserts any instance-local attributes - (from __attrs__) that have been set, combining them with **kwargs. + def request(self, method, url, + params=None, data=None, headers=None, cookies=None, files=None, auth=None, + timeout=None, allow_redirects=False, proxies=None, hooks=None, return_response=True): + + """Constructs and sends a :class:`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 or bytes to be sent in the query string for the :class:`Request`. + :param data: (optional) Dictionary or bytes to send in the body of the :class:`Request`. + :param headers: (optional) Dictionary of HTTP Headers to send with the :class:`Request`. + :param cookies: (optional) Dict or 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. + :param timeout: (optional) Float describing the timeout of the request. + :param allow_redirects: (optional) Boolean. Set to True if POST/PUT/DELETE redirect following is allowed. + :param proxies: (optional) Dictionary mapping protocol to the URL of the proxy. + :param return_response: (optional) If False, an un-sent Request object will returned. """ - def pass_args(func): - def wrapper_func(*args, **kwargs): + method = str(method).upper() + + if cookies is None: + cookies = {} + + if isinstance(cookies, dict): + cookies = add_dict_to_cookiejar(self.cookies, cookies) + + cookies = cookiejar_from_dict(cookies) - # Argument collector. - _kwargs = {} + # Expand header values + if headers: + for k, v in headers.items() or {}: + headers[k] = header_expand(v) - # If a session request has a cookie_dict, inject the - # values into the existing CookieJar instead. - if isinstance(kwargs.get('cookies', None), dict): - kwargs['cookies'] = add_dict_to_cookiejar( - self.cookies, kwargs['cookies'] - ) + args = dict( + method = method, + url = url, + data = data, + params = params, + headers = headers, + cookies = cookies, + files = files, + auth = auth, + hooks = hooks, + timeout = timeout or config.settings.timeout, + allow_redirects = allow_redirects, + proxies = proxies or config.settings.proxies, + ) - for attr in self.__attrs__: - # for attr in ['headers',]: - s_val = self.__dict__.get(attr) - r_val = kwargs.get(attr) + for attr in self.__attrs__: + session_val = getattr(self, attr, None) + local_val = args.get(attr) - new_attr = merge_kwargs(r_val, s_val) + args[attr] = merge_kwargs(local_val, session_val) - # Skip attributes that were set to None. - if new_attr is not None: - _kwargs[attr] = new_attr + # Arguments manipulation hook. + args = dispatch_hook('args', hooks, args) - # Make sure we didn't miss anything. - for (k, v) in kwargs.items(): - if k not in _kwargs: - _kwargs[k] = v + r = Request(**args) - return func(*args, **_kwargs) + # Pre-request hook. + r = dispatch_hook('pre_request', hooks, r) - return wrapper_func + # Don't send if asked nicely. + if not return_response: + return r + + # Send the HTTP Request. + r.send() + + # Post-request hook. + r = dispatch_hook('post_request', hooks, r) + + # Response manipulation hook. + r.response = dispatch_hook('response', hooks, r.response) + + return r.response + + def get(self, url, **kwargs): + """Sends a GET request. Returns :class:`Response` object. + + :param url: URL for the new :class:`Request` object. + :param **kwargs: Optional arguments that ``request`` takes. + """ - # Map and decorate each function available in requests.api - map(lambda fn: setattr(self, fn, pass_args(getattr(api, fn))), - api.__all__) + kwargs.setdefault('allow_redirects', True) + return self.request('GET', url, **kwargs) def session(**kwargs): -- 2.7.4