Mercurial > repos > shellac > guppy_basecaller
comparison env/lib/python3.7/site-packages/requests_toolbelt/adapters/appengine.py @ 2:6af9afd405e9 draft
"planemo upload commit 0a63dd5f4d38a1f6944587f52a8cd79874177fc1"
author | shellac |
---|---|
date | Thu, 14 May 2020 14:56:58 -0400 |
parents | 26e78fe6e8c4 |
children |
comparison
equal
deleted
inserted
replaced
1:75ca89e9b81c | 2:6af9afd405e9 |
---|---|
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 ) |