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