Mercurial > repos > shellac > guppy_basecaller
comparison 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 |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:26e78fe6e8c4 |
|---|---|
| 1 # -*- coding: utf-8 -*- | |
| 2 """The App Engine Transport Adapter for requests. | |
| 3 | |
| 4 .. versionadded:: 0.6.0 | |
| 5 | |
| 6 This requires a version of requests >= 2.10.0 and Python 2. | |
| 7 | |
| 8 There are two ways to use this library: | |
| 9 | |
| 10 #. If you're using requests directly, you can use code like: | |
| 11 | |
| 12 .. code-block:: python | |
| 13 | |
| 14 >>> import requests | |
| 15 >>> import ssl | |
| 16 >>> import requests.packages.urllib3.contrib.appengine as ul_appengine | |
| 17 >>> from requests_toolbelt.adapters import appengine | |
| 18 >>> s = requests.Session() | |
| 19 >>> if ul_appengine.is_appengine_sandbox(): | |
| 20 ... s.mount('http://', appengine.AppEngineAdapter()) | |
| 21 ... s.mount('https://', appengine.AppEngineAdapter()) | |
| 22 | |
| 23 #. If you depend on external libraries which use requests, you can use code | |
| 24 like: | |
| 25 | |
| 26 .. code-block:: python | |
| 27 | |
| 28 >>> from requests_toolbelt.adapters import appengine | |
| 29 >>> appengine.monkeypatch() | |
| 30 | |
| 31 which will ensure all requests.Session objects use AppEngineAdapter properly. | |
| 32 | |
| 33 You are also able to :ref:`disable certificate validation <insecure_appengine>` | |
| 34 when monkey-patching. | |
| 35 """ | |
| 36 import requests | |
| 37 import warnings | |
| 38 from requests import adapters | |
| 39 from requests import sessions | |
| 40 | |
| 41 from .. import exceptions as exc | |
| 42 from .._compat import gaecontrib | |
| 43 from .._compat import timeout | |
| 44 | |
| 45 | |
| 46 class AppEngineMROHack(adapters.HTTPAdapter): | |
| 47 """Resolves infinite recursion when monkeypatching. | |
| 48 | |
| 49 This works by injecting itself as the base class of both the | |
| 50 :class:`AppEngineAdapter` and Requests' default HTTPAdapter, which needs to | |
| 51 be done because default HTTPAdapter's MRO is recompiled when we | |
| 52 monkeypatch, at which point this class becomes HTTPAdapter's base class. | |
| 53 In addition, we use an instantiation flag to avoid infinite recursion. | |
| 54 """ | |
| 55 _initialized = False | |
| 56 | |
| 57 def __init__(self, *args, **kwargs): | |
| 58 if not self._initialized: | |
| 59 self._initialized = True | |
| 60 super(AppEngineMROHack, self).__init__(*args, **kwargs) | |
| 61 | |
| 62 | |
| 63 class AppEngineAdapter(AppEngineMROHack, adapters.HTTPAdapter): | |
| 64 """The transport adapter for Requests to use urllib3's GAE support. | |
| 65 | |
| 66 Implements Requests's HTTPAdapter API. | |
| 67 | |
| 68 When deploying to Google's App Engine service, some of Requests' | |
| 69 functionality is broken. There is underlying support for GAE in urllib3. | |
| 70 This functionality, however, is opt-in and needs to be enabled explicitly | |
| 71 for Requests to be able to use it. | |
| 72 """ | |
| 73 | |
| 74 __attrs__ = adapters.HTTPAdapter.__attrs__ + ['_validate_certificate'] | |
| 75 | |
| 76 def __init__(self, validate_certificate=True, *args, **kwargs): | |
| 77 _check_version() | |
| 78 self._validate_certificate = validate_certificate | |
| 79 super(AppEngineAdapter, self).__init__(*args, **kwargs) | |
| 80 | |
| 81 def init_poolmanager(self, connections, maxsize, block=False): | |
| 82 self.poolmanager = _AppEnginePoolManager(self._validate_certificate) | |
| 83 | |
| 84 | |
| 85 class InsecureAppEngineAdapter(AppEngineAdapter): | |
| 86 """An always-insecure GAE adapter for Requests. | |
| 87 | |
| 88 This is a variant of the the transport adapter for Requests to use | |
| 89 urllib3's GAE support that does not validate certificates. Use with | |
| 90 caution! | |
| 91 | |
| 92 .. note:: | |
| 93 The ``validate_certificate`` keyword argument will not be honored here | |
| 94 and is not part of the signature because we always force it to | |
| 95 ``False``. | |
| 96 | |
| 97 See :class:`AppEngineAdapter` for further details. | |
| 98 """ | |
| 99 | |
| 100 def __init__(self, *args, **kwargs): | |
| 101 if kwargs.pop("validate_certificate", False): | |
| 102 warnings.warn("Certificate validation cannot be specified on the " | |
| 103 "InsecureAppEngineAdapter, but was present. This " | |
| 104 "will be ignored and certificate validation will " | |
| 105 "remain off.", exc.IgnoringGAECertificateValidation) | |
| 106 | |
| 107 super(InsecureAppEngineAdapter, self).__init__( | |
| 108 validate_certificate=False, *args, **kwargs) | |
| 109 | |
| 110 | |
| 111 class _AppEnginePoolManager(object): | |
| 112 """Implements urllib3's PoolManager API expected by requests. | |
| 113 | |
| 114 While a real PoolManager map hostnames to reusable Connections, | |
| 115 AppEngine has no concept of a reusable connection to a host. | |
| 116 So instead, this class constructs a small Connection per request, | |
| 117 that is returned to the Adapter and used to access the URL. | |
| 118 """ | |
| 119 | |
| 120 def __init__(self, validate_certificate=True): | |
| 121 self.appengine_manager = gaecontrib.AppEngineManager( | |
| 122 validate_certificate=validate_certificate) | |
| 123 | |
| 124 def connection_from_url(self, url): | |
| 125 return _AppEngineConnection(self.appengine_manager, url) | |
| 126 | |
| 127 def clear(self): | |
| 128 pass | |
| 129 | |
| 130 | |
| 131 class _AppEngineConnection(object): | |
| 132 """Implements urllib3's HTTPConnectionPool API's urlopen(). | |
| 133 | |
| 134 This Connection's urlopen() is called with a host-relative path, | |
| 135 so in order to properly support opening the URL, we need to store | |
| 136 the full URL when this Connection is constructed from the PoolManager. | |
| 137 | |
| 138 This code wraps AppEngineManager.urlopen(), which exposes a different | |
| 139 API than in the original urllib3 urlopen(), and thus needs this adapter. | |
| 140 """ | |
| 141 | |
| 142 def __init__(self, appengine_manager, url): | |
| 143 self.appengine_manager = appengine_manager | |
| 144 self.url = url | |
| 145 | |
| 146 def urlopen(self, method, url, body=None, headers=None, retries=None, | |
| 147 redirect=True, assert_same_host=True, | |
| 148 timeout=timeout.Timeout.DEFAULT_TIMEOUT, | |
| 149 pool_timeout=None, release_conn=None, **response_kw): | |
| 150 # This function's url argument is a host-relative URL, | |
| 151 # but the AppEngineManager expects an absolute URL. | |
| 152 # So we saved out the self.url when the AppEngineConnection | |
| 153 # was constructed, which we then can use down below instead. | |
| 154 | |
| 155 # We once tried to verify our assumptions here, but sometimes the | |
| 156 # passed-in URL differs on url fragments, or "http://a.com" vs "/". | |
| 157 | |
| 158 # urllib3's App Engine adapter only uses Timeout.total, not read or | |
| 159 # connect. | |
| 160 if not timeout.total: | |
| 161 timeout.total = timeout._read or timeout._connect | |
| 162 | |
| 163 # Jump through the hoops necessary to call AppEngineManager's API. | |
| 164 return self.appengine_manager.urlopen( | |
| 165 method, | |
| 166 self.url, | |
| 167 body=body, | |
| 168 headers=headers, | |
| 169 retries=retries, | |
| 170 redirect=redirect, | |
| 171 timeout=timeout, | |
| 172 **response_kw) | |
| 173 | |
| 174 | |
| 175 def monkeypatch(validate_certificate=True): | |
| 176 """Sets up all Sessions to use AppEngineAdapter by default. | |
| 177 | |
| 178 If you don't want to deal with configuring your own Sessions, | |
| 179 or if you use libraries that use requests directly (ie requests.post), | |
| 180 then you may prefer to monkeypatch and auto-configure all Sessions. | |
| 181 | |
| 182 .. warning: : | |
| 183 | |
| 184 If ``validate_certificate`` is ``False``, certification validation will | |
| 185 effectively be disabled for all requests. | |
| 186 """ | |
| 187 _check_version() | |
| 188 # HACK: We should consider modifying urllib3 to support this cleanly, | |
| 189 # so that we can set a module-level variable in the sessions module, | |
| 190 # instead of overriding an imported HTTPAdapter as is done here. | |
| 191 adapter = AppEngineAdapter | |
| 192 if not validate_certificate: | |
| 193 adapter = InsecureAppEngineAdapter | |
| 194 | |
| 195 sessions.HTTPAdapter = adapter | |
| 196 adapters.HTTPAdapter = adapter | |
| 197 | |
| 198 | |
| 199 def _check_version(): | |
| 200 if gaecontrib is None: | |
| 201 raise exc.VersionMismatchError( | |
| 202 "The toolbelt requires at least Requests 2.10.0 to be " | |
| 203 "installed. Version {0} was found instead.".format( | |
| 204 requests.__version__ | |
| 205 ) | |
| 206 ) |
