github.com/phrase/openapi@v0.0.0-20240514140800-49e8a106740e/openapi-generator/templates/python/rest.mustache (about) 1 # coding: utf-8 2 3 {{>partial_header}} 4 5 from __future__ import absolute_import 6 7 import io 8 import json 9 import logging 10 import re 11 import ssl 12 13 import certifi 14 # python 2 and python 3 compatibility library 15 import six 16 from six.moves.urllib.parse import urlencode 17 import urllib3 18 19 from {{packageName}}.exceptions import ApiException, ApiValueError 20 21 22 logger = logging.getLogger(__name__) 23 24 25 class RESTResponse(io.IOBase): 26 27 def __init__(self, resp): 28 self.urllib3_response = resp 29 self.status = resp.status 30 self.reason = resp.reason 31 self.data = resp.data 32 33 def getheaders(self): 34 """Returns a dictionary of the response headers.""" 35 return self.urllib3_response.getheaders() 36 37 def getheader(self, name, default=None): 38 """Returns a given response header.""" 39 return self.urllib3_response.getheader(name, default) 40 41 def getencoding(self): 42 """Returns charset encoding returned by the server.""" 43 encoding = 'utf-8' 44 content_type = self.getheader('Content-Type') 45 if content_type: 46 m = re.search(r'charset=(\S+)', content_type) 47 if m: encoding = m.group(1) 48 49 return encoding 50 51 class RESTClientObject(object): 52 53 def __init__(self, configuration, pools_size=4, maxsize=None): 54 # urllib3.PoolManager will pass all kw parameters to connectionpool 55 # https://github.com/shazow/urllib3/blob/f9409436f83aeb79fbaf090181cd81b784f1b8ce/urllib3/poolmanager.py#L75 # noqa: E501 56 # https://github.com/shazow/urllib3/blob/f9409436f83aeb79fbaf090181cd81b784f1b8ce/urllib3/connectionpool.py#L680 # noqa: E501 57 # maxsize is the number of requests to host that are allowed in parallel # noqa: E501 58 # Custom SSL certificates and client certificates: http://urllib3.readthedocs.io/en/latest/advanced-usage.html # noqa: E501 59 60 # cert_reqs 61 if configuration.verify_ssl: 62 cert_reqs = ssl.CERT_REQUIRED 63 else: 64 cert_reqs = ssl.CERT_NONE 65 66 # ca_certs 67 if configuration.ssl_ca_cert: 68 ca_certs = configuration.ssl_ca_cert 69 else: 70 # if not set certificate file, use Mozilla's root certificates. 71 ca_certs = certifi.where() 72 73 addition_pool_args = {} 74 if configuration.assert_hostname is not None: 75 addition_pool_args['assert_hostname'] = configuration.assert_hostname # noqa: E501 76 77 if configuration.retries is not None: 78 addition_pool_args['retries'] = configuration.retries 79 80 if maxsize is None: 81 if configuration.connection_pool_maxsize is not None: 82 maxsize = configuration.connection_pool_maxsize 83 else: 84 maxsize = 4 85 86 # https pool manager 87 if configuration.proxy: 88 self.pool_manager = urllib3.ProxyManager( 89 num_pools=pools_size, 90 maxsize=maxsize, 91 cert_reqs=cert_reqs, 92 ca_certs=ca_certs, 93 cert_file=configuration.cert_file, 94 key_file=configuration.key_file, 95 proxy_url=configuration.proxy, 96 proxy_headers=configuration.proxy_headers, 97 **addition_pool_args 98 ) 99 else: 100 self.pool_manager = urllib3.PoolManager( 101 num_pools=pools_size, 102 maxsize=maxsize, 103 cert_reqs=cert_reqs, 104 ca_certs=ca_certs, 105 cert_file=configuration.cert_file, 106 key_file=configuration.key_file, 107 **addition_pool_args 108 ) 109 110 def request(self, method, url, query_params=None, headers=None, 111 body=None, post_params=None, _preload_content=True, 112 _request_timeout=None): 113 """Perform requests. 114 115 :param method: http request method 116 :param url: http request url 117 :param query_params: query parameters in the url 118 :param headers: http request headers 119 :param body: request json body, for `application/json` 120 :param post_params: request post parameters, 121 `application/x-www-form-urlencoded` 122 and `multipart/form-data` 123 :param _preload_content: if False, the urllib3.HTTPResponse object will 124 be returned without reading/decoding response 125 data. Default is True. 126 :param _request_timeout: timeout setting for this request. If one 127 number provided, it will be total request 128 timeout. It can also be a pair (tuple) of 129 (connection, read) timeouts. 130 """ 131 method = method.upper() 132 assert method in ['GET', 'HEAD', 'DELETE', 'POST', 'PUT', 133 'PATCH', 'OPTIONS'] 134 135 if post_params and body: 136 raise ApiValueError( 137 "body parameter cannot be used with post_params parameter." 138 ) 139 140 post_params = post_params or {} 141 headers = headers or {} 142 143 timeout = None 144 if _request_timeout: 145 if isinstance(_request_timeout, (int, ) if six.PY3 else (int, long)): # noqa: E501,F821 146 timeout = urllib3.Timeout(total=_request_timeout) 147 elif (isinstance(_request_timeout, tuple) and 148 len(_request_timeout) == 2): 149 timeout = urllib3.Timeout( 150 connect=_request_timeout[0], read=_request_timeout[1]) 151 152 if 'Content-Type' not in headers: 153 headers['Content-Type'] = 'application/json' 154 155 try: 156 # For `POST`, `PUT`, `PATCH`, `OPTIONS`, `DELETE` 157 if method in ['POST', 'PUT', 'PATCH', 'OPTIONS', 'DELETE']: 158 if query_params: 159 url += '?' + urlencode(query_params) 160 if re.search('json', headers['Content-Type'], re.IGNORECASE): 161 request_body = None 162 if body is not None: 163 request_body = json.dumps(body) 164 r = self.pool_manager.request( 165 method, url, 166 body=request_body, 167 preload_content=_preload_content, 168 timeout=timeout, 169 headers=headers) 170 elif headers['Content-Type'] == 'application/x-www-form-urlencoded': # noqa: E501 171 r = self.pool_manager.request( 172 method, url, 173 fields=post_params, 174 encode_multipart=False, 175 preload_content=_preload_content, 176 timeout=timeout, 177 headers=headers) 178 elif headers['Content-Type'] == 'multipart/form-data': 179 # must del headers['Content-Type'], or the correct 180 # Content-Type which generated by urllib3 will be 181 # overwritten. 182 del headers['Content-Type'] 183 r = self.pool_manager.request( 184 method, url, 185 fields=post_params, 186 encode_multipart=True, 187 preload_content=_preload_content, 188 timeout=timeout, 189 headers=headers) 190 # Pass a `string` parameter directly in the body to support 191 # other content types than Json when `body` argument is 192 # provided in serialized form 193 elif isinstance(body, str) or isinstance(body, bytes): 194 request_body = body 195 r = self.pool_manager.request( 196 method, url, 197 body=request_body, 198 preload_content=_preload_content, 199 timeout=timeout, 200 headers=headers) 201 else: 202 # Cannot generate the request from given parameters 203 msg = """Cannot prepare a request message for provided 204 arguments. Please check that your arguments match 205 declared content type.""" 206 raise ApiException(status=0, reason=msg) 207 # For `GET`, `HEAD` 208 else: 209 r = self.pool_manager.request(method, url, 210 fields=query_params, 211 preload_content=_preload_content, 212 timeout=timeout, 213 headers=headers) 214 except urllib3.exceptions.SSLError as e: 215 msg = "{0}\n{1}".format(type(e).__name__, str(e)) 216 raise ApiException(status=0, reason=msg) 217 218 if _preload_content: 219 r = RESTResponse(r) 220 221 # In the python 3, the response.data is bytes. 222 # we need to decode it to string. 223 if six.PY3: 224 r.data = r.data.decode(r.getencoding()) 225 226 # log response body 227 logger.debug("response body: %s", r.data) 228 229 if not 200 <= r.status <= 299: 230 raise ApiException(http_resp=r) 231 232 return r 233 234 def GET(self, url, headers=None, query_params=None, _preload_content=True, 235 _request_timeout=None): 236 return self.request("GET", url, 237 headers=headers, 238 _preload_content=_preload_content, 239 _request_timeout=_request_timeout, 240 query_params=query_params) 241 242 def HEAD(self, url, headers=None, query_params=None, _preload_content=True, 243 _request_timeout=None): 244 return self.request("HEAD", url, 245 headers=headers, 246 _preload_content=_preload_content, 247 _request_timeout=_request_timeout, 248 query_params=query_params) 249 250 def OPTIONS(self, url, headers=None, query_params=None, post_params=None, 251 body=None, _preload_content=True, _request_timeout=None): 252 return self.request("OPTIONS", url, 253 headers=headers, 254 query_params=query_params, 255 post_params=post_params, 256 _preload_content=_preload_content, 257 _request_timeout=_request_timeout, 258 body=body) 259 260 def DELETE(self, url, headers=None, query_params=None, body=None, 261 _preload_content=True, _request_timeout=None): 262 return self.request("DELETE", url, 263 headers=headers, 264 query_params=query_params, 265 _preload_content=_preload_content, 266 _request_timeout=_request_timeout, 267 body=body) 268 269 def POST(self, url, headers=None, query_params=None, post_params=None, 270 body=None, _preload_content=True, _request_timeout=None): 271 return self.request("POST", url, 272 headers=headers, 273 query_params=query_params, 274 post_params=post_params, 275 _preload_content=_preload_content, 276 _request_timeout=_request_timeout, 277 body=body) 278 279 def PUT(self, url, headers=None, query_params=None, post_params=None, 280 body=None, _preload_content=True, _request_timeout=None): 281 return self.request("PUT", url, 282 headers=headers, 283 query_params=query_params, 284 post_params=post_params, 285 _preload_content=_preload_content, 286 _request_timeout=_request_timeout, 287 body=body) 288 289 def PATCH(self, url, headers=None, query_params=None, post_params=None, 290 body=None, _preload_content=True, _request_timeout=None): 291 return self.request("PATCH", url, 292 headers=headers, 293 query_params=query_params, 294 post_params=post_params, 295 _preload_content=_preload_content, 296 _request_timeout=_request_timeout, 297 body=body)