summaryrefslogtreecommitdiff
path: root/requests-0.14.0/requests/sessions.py
diff options
context:
space:
mode:
Diffstat (limited to 'requests-0.14.0/requests/sessions.py')
-rw-r--r--requests-0.14.0/requests/sessions.py328
1 files changed, 328 insertions, 0 deletions
diff --git a/requests-0.14.0/requests/sessions.py b/requests-0.14.0/requests/sessions.py
new file mode 100644
index 0000000..f0d4f3c
--- /dev/null
+++ b/requests-0.14.0/requests/sessions.py
@@ -0,0 +1,328 @@
+# -*- coding: utf-8 -*-
+
+"""
+requests.session
+~~~~~~~~~~~~~~~~
+
+This module provides a Session object to manage and persist settings across
+requests (cookies, auth, proxies).
+
+"""
+
+from copy import deepcopy
+from .compat import cookielib
+from .cookies import cookiejar_from_dict, remove_cookie_by_name
+from .defaults import defaults
+from .models import Request
+from .hooks import dispatch_hook
+from .utils import header_expand, from_key_val_list
+from .packages.urllib3.poolmanager import PoolManager
+
+
+def merge_kwargs(local_kwarg, default_kwarg):
+ """Merges kwarg dictionaries.
+
+ If a local key in the dictionary is set to None, it will be removed.
+ """
+
+ if default_kwarg is None:
+ return local_kwarg
+
+ if isinstance(local_kwarg, str):
+ return local_kwarg
+
+ if local_kwarg is None:
+ return default_kwarg
+
+ # Bypass if not a dictionary (e.g. timeout)
+ if not hasattr(default_kwarg, 'items'):
+ return local_kwarg
+
+ default_kwarg = from_key_val_list(default_kwarg)
+ local_kwarg = from_key_val_list(local_kwarg)
+
+ # Update new values.
+ kwargs = default_kwarg.copy()
+ kwargs.update(local_kwarg)
+
+ # Remove keys that are set to None.
+ for (k, v) in local_kwarg.items():
+ if v is None:
+ del kwargs[k]
+
+ return kwargs
+
+
+class Session(object):
+ """A Requests session."""
+
+ __attrs__ = [
+ 'headers', 'cookies', 'auth', 'timeout', 'proxies', 'hooks',
+ 'params', 'config', 'verify', 'cert', 'prefetch']
+
+ def __init__(self,
+ headers=None,
+ cookies=None,
+ auth=None,
+ timeout=None,
+ proxies=None,
+ hooks=None,
+ params=None,
+ config=None,
+ prefetch=True,
+ verify=True,
+ cert=None):
+
+ self.headers = from_key_val_list(headers or [])
+ self.auth = auth
+ self.timeout = timeout
+ self.proxies = from_key_val_list(proxies or [])
+ self.hooks = from_key_val_list(hooks or {})
+ self.params = from_key_val_list(params or [])
+ self.config = from_key_val_list(config or {})
+ self.prefetch = prefetch
+ self.verify = verify
+ self.cert = cert
+
+ for (k, v) in list(defaults.items()):
+ self.config.setdefault(k, deepcopy(v))
+
+ self.init_poolmanager()
+
+ # Set up a CookieJar to be used by default
+ if isinstance(cookies, cookielib.CookieJar):
+ self.cookies = cookies
+ else:
+ self.cookies = cookiejar_from_dict(cookies)
+
+ def init_poolmanager(self):
+ self.poolmanager = PoolManager(
+ num_pools=self.config.get('pool_connections'),
+ maxsize=self.config.get('pool_maxsize')
+ )
+
+ def __repr__(self):
+ return '<requests-client at 0x%x>' % (id(self))
+
+ def __enter__(self):
+ return self
+
+ def __exit__(self, *args):
+ self.close()
+
+ def close(self):
+ """Dispose of any internal state.
+
+ Currently, this just closes the PoolManager, which closes pooled
+ connections.
+ """
+ self.poolmanager.clear()
+
+ def request(self, method, url,
+ params=None,
+ data=None,
+ headers=None,
+ cookies=None,
+ files=None,
+ auth=None,
+ timeout=None,
+ allow_redirects=True,
+ proxies=None,
+ hooks=None,
+ return_response=True,
+ config=None,
+ prefetch=None,
+ verify=None,
+ cert=None):
+
+ """Constructs and sends a :class:`Request <Request>`.
+ Returns :class:`Response <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) Auth tuple or callable to enable Basic/Digest/Custom HTTP Auth.
+ :param timeout: (optional) Float describing the timeout of the request.
+ :param allow_redirects: (optional) Boolean. Set to True by default.
+ :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.
+ :param config: (optional) A configuration dictionary. See ``request.defaults`` for allowed keys and their default values.
+ :param prefetch: (optional) whether to immediately download the response content. Defaults to ``True``.
+ :param verify: (optional) if ``True``, the SSL cert will be verified. A CA_BUNDLE path can also be provided.
+ :param cert: (optional) if String, path to ssl client cert file (.pem). If Tuple, ('cert', 'key') pair.
+ """
+
+ method = str(method).upper()
+
+ # Default empty dicts for dict params.
+ data = [] if data is None else data
+ files = [] if files is None else files
+ headers = {} if headers is None else headers
+ params = {} if params is None else params
+ hooks = {} if hooks is None else hooks
+ prefetch = prefetch if prefetch is not None else self.prefetch
+
+ # use session's hooks as defaults
+ for key, cb in list(self.hooks.items()):
+ hooks.setdefault(key, cb)
+
+ # Expand header values.
+ if headers:
+ for k, v in list(headers.items() or {}):
+ headers[k] = header_expand(v)
+
+ args = dict(
+ method=method,
+ url=url,
+ data=data,
+ params=from_key_val_list(params),
+ headers=from_key_val_list(headers),
+ cookies=cookies,
+ files=files,
+ auth=auth,
+ hooks=from_key_val_list(hooks),
+ timeout=timeout,
+ allow_redirects=allow_redirects,
+ proxies=from_key_val_list(proxies),
+ config=from_key_val_list(config),
+ prefetch=prefetch,
+ verify=verify,
+ cert=cert,
+ _poolmanager=self.poolmanager
+ )
+
+ # merge session cookies into passed-in ones
+ dead_cookies = None
+ # passed-in cookies must become a CookieJar:
+ if not isinstance(cookies, cookielib.CookieJar):
+ args['cookies'] = cookiejar_from_dict(cookies)
+ # support unsetting cookies that have been passed in with None values
+ # this is only meaningful when `cookies` is a dict ---
+ # for a real CookieJar, the client should use session.cookies.clear()
+ if cookies is not None:
+ dead_cookies = [name for name in cookies if cookies[name] is None]
+ # merge the session's cookies into the passed-in cookies:
+ for cookie in self.cookies:
+ args['cookies'].set_cookie(cookie)
+ # remove the unset cookies from the jar we'll be using with the current request
+ # (but not from the session's own store of cookies):
+ if dead_cookies is not None:
+ for name in dead_cookies:
+ remove_cookie_by_name(args['cookies'], name)
+
+ # Merge local kwargs with session kwargs.
+ for attr in self.__attrs__:
+ # we already merged cookies:
+ if attr == 'cookies':
+ continue
+
+ session_val = getattr(self, attr, None)
+ local_val = args.get(attr)
+ args[attr] = merge_kwargs(local_val, session_val)
+
+ # Arguments manipulation hook.
+ args = dispatch_hook('args', args['hooks'], args)
+
+ # Create the (empty) response.
+ r = Request(**args)
+
+ # Give the response some context.
+ r.session = self
+
+ # Don't send if asked nicely.
+ if not return_response:
+ return r
+
+ # Send the HTTP Request.
+ r.send(prefetch=prefetch)
+
+ # Return the 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.
+ """
+
+ kwargs.setdefault('allow_redirects', True)
+ return self.request('get', url, **kwargs)
+
+ def options(self, url, **kwargs):
+ """Sends a OPTIONS request. Returns :class:`Response` object.
+
+ :param url: URL for the new :class:`Request` object.
+ :param \*\*kwargs: Optional arguments that ``request`` takes.
+ """
+
+ kwargs.setdefault('allow_redirects', True)
+ return self.request('options', url, **kwargs)
+
+ def head(self, url, **kwargs):
+ """Sends a HEAD request. Returns :class:`Response` object.
+
+ :param url: URL for the new :class:`Request` object.
+ :param \*\*kwargs: Optional arguments that ``request`` takes.
+ """
+
+ kwargs.setdefault('allow_redirects', False)
+ return self.request('head', url, **kwargs)
+
+ def post(self, url, data=None, **kwargs):
+ """Sends a POST request. Returns :class:`Response` object.
+
+ :param url: URL for the new :class:`Request` object.
+ :param data: (optional) Dictionary or bytes to send in the body of the :class:`Request`.
+ :param \*\*kwargs: Optional arguments that ``request`` takes.
+ """
+
+ return self.request('post', url, data=data, **kwargs)
+
+ def put(self, url, data=None, **kwargs):
+ """Sends a PUT request. Returns :class:`Response` object.
+
+ :param url: URL for the new :class:`Request` object.
+ :param data: (optional) Dictionary or bytes to send in the body of the :class:`Request`.
+ :param \*\*kwargs: Optional arguments that ``request`` takes.
+ """
+
+ return self.request('put', url, data=data, **kwargs)
+
+ def patch(self, url, data=None, **kwargs):
+ """Sends a PATCH request. Returns :class:`Response` object.
+
+ :param url: URL for the new :class:`Request` object.
+ :param data: (optional) Dictionary or bytes to send in the body of the :class:`Request`.
+ :param \*\*kwargs: Optional arguments that ``request`` takes.
+ """
+
+ return self.request('patch', url, data=data, **kwargs)
+
+ def delete(self, url, **kwargs):
+ """Sends a DELETE request. Returns :class:`Response` object.
+
+ :param url: URL for the new :class:`Request` object.
+ :param \*\*kwargs: Optional arguments that ``request`` takes.
+ """
+
+ return self.request('delete', url, **kwargs)
+
+ def __getstate__(self):
+ return dict((attr, getattr(self, attr, None)) for attr in self.__attrs__)
+
+ def __setstate__(self, state):
+ for attr, value in state.items():
+ setattr(self, attr, value)
+
+ self.init_poolmanager()
+
+
+def session(**kwargs):
+ """Returns a :class:`Session` for context-management."""
+
+ return Session(**kwargs)