diff env/lib/python3.7/site-packages/requests_toolbelt/adapters/appengine.py @ 0:26e78fe6e8c4 draft

"planemo upload commit c699937486c35866861690329de38ec1a5d9f783"
author shellac
date Sat, 02 May 2020 07:14:21 -0400
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/env/lib/python3.7/site-packages/requests_toolbelt/adapters/appengine.py	Sat May 02 07:14:21 2020 -0400
@@ -0,0 +1,206 @@
+# -*- coding: utf-8 -*-
+"""The App Engine Transport Adapter for requests.
+
+.. versionadded:: 0.6.0
+
+This requires a version of requests >= 2.10.0 and Python 2.
+
+There are two ways to use this library:
+
+#. If you're using requests directly, you can use code like:
+
+   .. code-block:: python
+
+       >>> import requests
+       >>> import ssl
+       >>> import requests.packages.urllib3.contrib.appengine as ul_appengine
+       >>> from requests_toolbelt.adapters import appengine
+       >>> s = requests.Session()
+       >>> if ul_appengine.is_appengine_sandbox():
+       ...    s.mount('http://', appengine.AppEngineAdapter())
+       ...    s.mount('https://', appengine.AppEngineAdapter())
+
+#. If you depend on external libraries which use requests, you can use code
+   like:
+
+   .. code-block:: python
+
+       >>> from requests_toolbelt.adapters import appengine
+       >>> appengine.monkeypatch()
+
+which will ensure all requests.Session objects use AppEngineAdapter properly.
+
+You are also able to :ref:`disable certificate validation <insecure_appengine>`
+when monkey-patching.
+"""
+import requests
+import warnings
+from requests import adapters
+from requests import sessions
+
+from .. import exceptions as exc
+from .._compat import gaecontrib
+from .._compat import timeout
+
+
+class AppEngineMROHack(adapters.HTTPAdapter):
+    """Resolves infinite recursion when monkeypatching.
+
+    This works by injecting itself as the base class of both the
+    :class:`AppEngineAdapter` and Requests' default HTTPAdapter, which needs to
+    be done because default HTTPAdapter's MRO is recompiled when we
+    monkeypatch, at which point this class becomes HTTPAdapter's base class.
+    In addition, we use an instantiation flag to avoid infinite recursion.
+    """
+    _initialized = False
+
+    def __init__(self, *args, **kwargs):
+        if not self._initialized:
+            self._initialized = True
+            super(AppEngineMROHack, self).__init__(*args, **kwargs)
+
+
+class AppEngineAdapter(AppEngineMROHack, adapters.HTTPAdapter):
+    """The transport adapter for Requests to use urllib3's GAE support.
+
+    Implements Requests's HTTPAdapter API.
+
+    When deploying to Google's App Engine service, some of Requests'
+    functionality is broken. There is underlying support for GAE in urllib3.
+    This functionality, however, is opt-in and needs to be enabled explicitly
+    for Requests to be able to use it.
+    """
+
+    __attrs__ = adapters.HTTPAdapter.__attrs__ + ['_validate_certificate']
+
+    def __init__(self, validate_certificate=True, *args, **kwargs):
+        _check_version()
+        self._validate_certificate = validate_certificate
+        super(AppEngineAdapter, self).__init__(*args, **kwargs)
+
+    def init_poolmanager(self, connections, maxsize, block=False):
+        self.poolmanager = _AppEnginePoolManager(self._validate_certificate)
+
+
+class InsecureAppEngineAdapter(AppEngineAdapter):
+    """An always-insecure GAE adapter for Requests.
+
+    This is a variant of the the transport adapter for Requests to use
+    urllib3's GAE support that does not validate certificates. Use with
+    caution!
+
+    .. note::
+        The ``validate_certificate`` keyword argument will not be honored here
+        and is not part of the signature because we always force it to
+        ``False``.
+
+    See :class:`AppEngineAdapter` for further details.
+    """
+
+    def __init__(self, *args, **kwargs):
+        if kwargs.pop("validate_certificate", False):
+            warnings.warn("Certificate validation cannot be specified on the "
+                          "InsecureAppEngineAdapter, but was present. This "
+                          "will be ignored and certificate validation will "
+                          "remain off.", exc.IgnoringGAECertificateValidation)
+
+        super(InsecureAppEngineAdapter, self).__init__(
+            validate_certificate=False, *args, **kwargs)
+
+
+class _AppEnginePoolManager(object):
+    """Implements urllib3's PoolManager API expected by requests.
+
+    While a real PoolManager map hostnames to reusable Connections,
+    AppEngine has no concept of a reusable connection to a host.
+    So instead, this class constructs a small Connection per request,
+    that is returned to the Adapter and used to access the URL.
+    """
+
+    def __init__(self, validate_certificate=True):
+        self.appengine_manager = gaecontrib.AppEngineManager(
+            validate_certificate=validate_certificate)
+
+    def connection_from_url(self, url):
+        return _AppEngineConnection(self.appengine_manager, url)
+
+    def clear(self):
+        pass
+
+
+class _AppEngineConnection(object):
+    """Implements urllib3's HTTPConnectionPool API's urlopen().
+
+    This Connection's urlopen() is called with a host-relative path,
+    so in order to properly support opening the URL, we need to store
+    the full URL when this Connection is constructed from the PoolManager.
+
+    This code wraps AppEngineManager.urlopen(), which exposes a different
+    API than in the original urllib3 urlopen(), and thus needs this adapter.
+    """
+
+    def __init__(self, appengine_manager, url):
+        self.appengine_manager = appengine_manager
+        self.url = url
+
+    def urlopen(self, method, url, body=None, headers=None, retries=None,
+                redirect=True, assert_same_host=True,
+                timeout=timeout.Timeout.DEFAULT_TIMEOUT,
+                pool_timeout=None, release_conn=None, **response_kw):
+        # This function's url argument is a host-relative URL,
+        # but the AppEngineManager expects an absolute URL.
+        # So we saved out the self.url when the AppEngineConnection
+        # was constructed, which we then can use down below instead.
+
+        # We once tried to verify our assumptions here, but sometimes the
+        # passed-in URL differs on url fragments, or "http://a.com" vs "/".
+
+        # urllib3's App Engine adapter only uses Timeout.total, not read or
+        # connect.
+        if not timeout.total:
+            timeout.total = timeout._read or timeout._connect
+
+        # Jump through the hoops necessary to call AppEngineManager's API.
+        return self.appengine_manager.urlopen(
+            method,
+            self.url,
+            body=body,
+            headers=headers,
+            retries=retries,
+            redirect=redirect,
+            timeout=timeout,
+            **response_kw)
+
+
+def monkeypatch(validate_certificate=True):
+    """Sets up all Sessions to use AppEngineAdapter by default.
+
+    If you don't want to deal with configuring your own Sessions,
+    or if you use libraries that use requests directly (ie requests.post),
+    then you may prefer to monkeypatch and auto-configure all Sessions.
+
+    .. warning: :
+
+        If ``validate_certificate`` is ``False``, certification validation will
+        effectively be disabled for all requests.
+    """
+    _check_version()
+    # HACK: We should consider modifying urllib3 to support this cleanly,
+    # so that we can set a module-level variable in the sessions module,
+    # instead of overriding an imported HTTPAdapter as is done here.
+    adapter = AppEngineAdapter
+    if not validate_certificate:
+        adapter = InsecureAppEngineAdapter
+
+    sessions.HTTPAdapter = adapter
+    adapters.HTTPAdapter = adapter
+
+
+def _check_version():
+    if gaecontrib is None:
+        raise exc.VersionMismatchError(
+            "The toolbelt requires at least Requests 2.10.0 to be "
+            "installed. Version {0} was found instead.".format(
+                requests.__version__
+            )
+        )