github.com/filecoin-project/bacalhau@v0.3.23-0.20230228154132-45c989550ace/clients/python/bacalhau_apiclient/api_client.py (about)

     1  # coding: utf-8
     2  """
     3      Bacalhau API
     4  
     5      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
     6  
     7      OpenAPI spec version: 0.3.22.post4
     8      Contact: team@bacalhau.org
     9      Generated by: https://github.com/swagger-api/swagger-codegen.git
    10  """
    11  
    12  from __future__ import absolute_import
    13  
    14  import datetime
    15  import json
    16  import mimetypes
    17  from multiprocessing.pool import ThreadPool
    18  import os
    19  import re
    20  import tempfile
    21  
    22  # python 2 and python 3 compatibility library
    23  import six
    24  from six.moves.urllib.parse import quote
    25  
    26  from bacalhau_apiclient.configuration import Configuration
    27  import bacalhau_apiclient.models
    28  from bacalhau_apiclient import rest
    29  
    30  
    31  class ApiClient(object):
    32      """Generic API client for Swagger client library builds.
    33  
    34      Swagger generic API client. This client handles the client-
    35      server communication, and is invariant across implementations. Specifics of
    36      the methods and models for each application are generated from the Swagger
    37      templates.
    38  
    39      NOTE: This class is auto generated by the swagger code generator program.
    40      Ref: https://github.com/swagger-api/swagger-codegen
    41      Do not edit the class manually.
    42  
    43      :param configuration: .Configuration object for this client
    44      :param header_name: a header to pass when making calls to the API.
    45      :param header_value: a header value to pass when making calls to
    46          the API.
    47      :param cookie: a cookie to include in the header when making calls
    48          to the API
    49      """
    50  
    51      PRIMITIVE_TYPES = (float, bool, bytes, six.text_type) + six.integer_types
    52      NATIVE_TYPES_MAPPING = {
    53          'int': int,
    54          'long': int if six.PY3 else long,  # noqa: F821
    55          'float': float,
    56          'str': str,
    57          'bool': bool,
    58          'date': datetime.date,
    59          'datetime': datetime.datetime,
    60          'object': object,
    61      }
    62  
    63      def __init__(self, configuration=None, header_name=None, header_value=None,
    64                   cookie=None):
    65          if configuration is None:
    66              configuration = Configuration()
    67          self.configuration = configuration
    68  
    69          # Use the pool property to lazily initialize the ThreadPool.
    70          self._pool = None
    71          self.rest_client = rest.RESTClientObject(configuration)
    72          self.default_headers = {}
    73          if header_name is not None:
    74              self.default_headers[header_name] = header_value
    75          self.cookie = cookie
    76          # Set default User-Agent.
    77          self.user_agent = 'Swagger-Codegen/0.3.22.post4/python'
    78          self.client_side_validation = configuration.client_side_validation
    79  
    80      def __del__(self):
    81          if self._pool is not None:
    82              self._pool.close()
    83              self._pool.join()
    84  
    85      @property
    86      def pool(self):
    87          if self._pool is None:
    88              self._pool = ThreadPool()
    89          return self._pool
    90  
    91      @property
    92      def user_agent(self):
    93          """User agent for this API client"""
    94          return self.default_headers['User-Agent']
    95  
    96      @user_agent.setter
    97      def user_agent(self, value):
    98          self.default_headers['User-Agent'] = value
    99  
   100      def set_default_header(self, header_name, header_value):
   101          self.default_headers[header_name] = header_value
   102  
   103      def __call_api(
   104              self, resource_path, method, path_params=None,
   105              query_params=None, header_params=None, body=None, post_params=None,
   106              files=None, response_type=None, auth_settings=None,
   107              _return_http_data_only=None, collection_formats=None,
   108              _preload_content=True, _request_timeout=None):
   109  
   110          config = self.configuration
   111  
   112          # header parameters
   113          header_params = header_params or {}
   114          header_params.update(self.default_headers)
   115          if self.cookie:
   116              header_params['Cookie'] = self.cookie
   117          if header_params:
   118              header_params = self.sanitize_for_serialization(header_params)
   119              header_params = dict(self.parameters_to_tuples(header_params,
   120                                                             collection_formats))
   121  
   122          # path parameters
   123          if path_params:
   124              path_params = self.sanitize_for_serialization(path_params)
   125              path_params = self.parameters_to_tuples(path_params,
   126                                                      collection_formats)
   127              for k, v in path_params:
   128                  # specified safe chars, encode everything
   129                  resource_path = resource_path.replace(
   130                      '{%s}' % k,
   131                      quote(str(v), safe=config.safe_chars_for_path_param)
   132                  )
   133  
   134          # query parameters
   135          if query_params:
   136              query_params = self.sanitize_for_serialization(query_params)
   137              query_params = self.parameters_to_tuples(query_params,
   138                                                       collection_formats)
   139  
   140          # post parameters
   141          if post_params or files:
   142              post_params = self.prepare_post_parameters(post_params, files)
   143              post_params = self.sanitize_for_serialization(post_params)
   144              post_params = self.parameters_to_tuples(post_params,
   145                                                      collection_formats)
   146  
   147          # auth setting
   148          self.update_params_for_auth(header_params, query_params, auth_settings)
   149  
   150          # body
   151          if body:
   152              body = self.sanitize_for_serialization(body)
   153  
   154          # request url
   155          url = self.configuration.host + resource_path
   156  
   157          # perform request and return response
   158          response_data = self.request(
   159              method, url, query_params=query_params, headers=header_params,
   160              post_params=post_params, body=body,
   161              _preload_content=_preload_content,
   162              _request_timeout=_request_timeout)
   163  
   164          self.last_response = response_data
   165  
   166          return_data = response_data
   167          if _preload_content:
   168              # deserialize response data
   169              if response_type:
   170                  return_data = self.deserialize(response_data, response_type)
   171              else:
   172                  return_data = None
   173  
   174          if _return_http_data_only:
   175              return (return_data)
   176          else:
   177              return (return_data, response_data.status,
   178                      response_data.getheaders())
   179  
   180      def sanitize_for_serialization(self, obj):
   181          """Builds a JSON POST object.
   182  
   183          If obj is None, return None.
   184          If obj is str, int, long, float, bool, return directly.
   185          If obj is datetime.datetime, datetime.date
   186              convert to string in iso8601 format.
   187          If obj is list, sanitize each element in the list.
   188          If obj is dict, return the dict.
   189          If obj is swagger model, return the properties dict.
   190  
   191          :param obj: The data to serialize.
   192          :return: The serialized form of data.
   193          """
   194          if obj is None:
   195              return None
   196          elif isinstance(obj, self.PRIMITIVE_TYPES):
   197              return obj
   198          elif isinstance(obj, list):
   199              return [self.sanitize_for_serialization(sub_obj)
   200                      for sub_obj in obj]
   201          elif isinstance(obj, tuple):
   202              return tuple(self.sanitize_for_serialization(sub_obj)
   203                           for sub_obj in obj)
   204          elif isinstance(obj, (datetime.datetime, datetime.date)):
   205              return obj.isoformat()
   206  
   207          if isinstance(obj, dict):
   208              obj_dict = obj
   209          else:
   210              # Convert model obj to dict except
   211              # attributes `swagger_types`, `attribute_map`
   212              # and attributes which value is not None.
   213              # Convert attribute name to json key in
   214              # model definition for request.
   215              obj_dict = {obj.attribute_map[attr]: getattr(obj, attr)
   216                          for attr, _ in six.iteritems(obj.swagger_types)
   217                          if getattr(obj, attr) is not None}
   218  
   219          return {key: self.sanitize_for_serialization(val)
   220                  for key, val in six.iteritems(obj_dict)}
   221  
   222      def deserialize(self, response, response_type):
   223          """Deserializes response into an object.
   224  
   225          :param response: RESTResponse object to be deserialized.
   226          :param response_type: class literal for
   227              deserialized object, or string of class name.
   228  
   229          :return: deserialized object.
   230          """
   231          # handle file downloading
   232          # save response body into a tmp file and return the instance
   233          if response_type == "file":
   234              return self.__deserialize_file(response)
   235  
   236          # fetch data from response object
   237          try:
   238              data = json.loads(response.data)
   239          except ValueError:
   240              data = response.data
   241  
   242          return self.__deserialize(data, response_type)
   243  
   244      def __deserialize(self, data, klass):
   245          """Deserializes dict, list, str into an object.
   246  
   247          :param data: dict, list or str.
   248          :param klass: class literal, or string of class name.
   249  
   250          :return: object.
   251          """
   252          if data is None:
   253              return None
   254  
   255          if type(klass) == str:
   256              if klass.startswith('list['):
   257                  sub_kls = re.match(r'list\[(.*)\]', klass).group(1)
   258                  return [self.__deserialize(sub_data, sub_kls)
   259                          for sub_data in data]
   260  
   261              if klass.startswith('dict('):
   262                  sub_kls = re.match(r'dict\(([^,]*), (.*)\)', klass).group(2)
   263                  return {k: self.__deserialize(v, sub_kls)
   264                          for k, v in six.iteritems(data)}
   265  
   266              # convert str to class
   267              if klass in self.NATIVE_TYPES_MAPPING:
   268                  klass = self.NATIVE_TYPES_MAPPING[klass]
   269              else:
   270                  klass = getattr(bacalhau_apiclient.models, klass)
   271  
   272          if klass in self.PRIMITIVE_TYPES:
   273              return self.__deserialize_primitive(data, klass)
   274          elif klass == object:
   275              return self.__deserialize_object(data)
   276          elif klass == datetime.date:
   277              return self.__deserialize_date(data)
   278          elif klass == datetime.datetime:
   279              return self.__deserialize_datatime(data)
   280          else:
   281              return self.__deserialize_model(data, klass)
   282  
   283      def call_api(self, resource_path, method,
   284                   path_params=None, query_params=None, header_params=None,
   285                   body=None, post_params=None, files=None,
   286                   response_type=None, auth_settings=None, async_req=None,
   287                   _return_http_data_only=None, collection_formats=None,
   288                   _preload_content=True, _request_timeout=None):
   289          """Makes the HTTP request (synchronous) and returns deserialized data.
   290  
   291          To make an async request, set the async_req parameter.
   292  
   293          :param resource_path: Path to method endpoint.
   294          :param method: Method to call.
   295          :param path_params: Path parameters in the url.
   296          :param query_params: Query parameters in the url.
   297          :param header_params: Header parameters to be
   298              placed in the request header.
   299          :param body: Request body.
   300          :param post_params dict: Request post form parameters,
   301              for `application/x-www-form-urlencoded`, `multipart/form-data`.
   302          :param auth_settings list: Auth Settings names for the request.
   303          :param response: Response data type.
   304          :param files dict: key -> filename, value -> filepath,
   305              for `multipart/form-data`.
   306          :param async_req bool: execute request asynchronously
   307          :param _return_http_data_only: response data without head status code
   308                                         and headers
   309          :param collection_formats: dict of collection formats for path, query,
   310              header, and post parameters.
   311          :param _preload_content: if False, the urllib3.HTTPResponse object will
   312                                   be returned without reading/decoding response
   313                                   data. Default is True.
   314          :param _request_timeout: timeout setting for this request. If one
   315                                   number provided, it will be total request
   316                                   timeout. It can also be a pair (tuple) of
   317                                   (connection, read) timeouts.
   318          :return:
   319              If async_req parameter is True,
   320              the request will be called asynchronously.
   321              The method will return the request thread.
   322              If parameter async_req is False or missing,
   323              then the method will return the response directly.
   324          """
   325          if not async_req:
   326              return self.__call_api(resource_path, method,
   327                                     path_params, query_params, header_params,
   328                                     body, post_params, files,
   329                                     response_type, auth_settings,
   330                                     _return_http_data_only, collection_formats,
   331                                     _preload_content, _request_timeout)
   332          else:
   333              thread = self.pool.apply_async(self.__call_api, (resource_path,
   334                                             method, path_params, query_params,
   335                                             header_params, body,
   336                                             post_params, files,
   337                                             response_type, auth_settings,
   338                                             _return_http_data_only,
   339                                             collection_formats,
   340                                             _preload_content, _request_timeout))
   341          return thread
   342  
   343      def request(self, method, url, query_params=None, headers=None,
   344                  post_params=None, body=None, _preload_content=True,
   345                  _request_timeout=None):
   346          """Makes the HTTP request using RESTClient."""
   347          if method == "GET":
   348              return self.rest_client.GET(url,
   349                                          query_params=query_params,
   350                                          _preload_content=_preload_content,
   351                                          _request_timeout=_request_timeout,
   352                                          headers=headers)
   353          elif method == "HEAD":
   354              return self.rest_client.HEAD(url,
   355                                           query_params=query_params,
   356                                           _preload_content=_preload_content,
   357                                           _request_timeout=_request_timeout,
   358                                           headers=headers)
   359          elif method == "OPTIONS":
   360              return self.rest_client.OPTIONS(url,
   361                                              query_params=query_params,
   362                                              headers=headers,
   363                                              post_params=post_params,
   364                                              _preload_content=_preload_content,
   365                                              _request_timeout=_request_timeout,
   366                                              body=body)
   367          elif method == "POST":
   368              return self.rest_client.POST(url,
   369                                           query_params=query_params,
   370                                           headers=headers,
   371                                           post_params=post_params,
   372                                           _preload_content=_preload_content,
   373                                           _request_timeout=_request_timeout,
   374                                           body=body)
   375          elif method == "PUT":
   376              return self.rest_client.PUT(url,
   377                                          query_params=query_params,
   378                                          headers=headers,
   379                                          post_params=post_params,
   380                                          _preload_content=_preload_content,
   381                                          _request_timeout=_request_timeout,
   382                                          body=body)
   383          elif method == "PATCH":
   384              return self.rest_client.PATCH(url,
   385                                            query_params=query_params,
   386                                            headers=headers,
   387                                            post_params=post_params,
   388                                            _preload_content=_preload_content,
   389                                            _request_timeout=_request_timeout,
   390                                            body=body)
   391          elif method == "DELETE":
   392              return self.rest_client.DELETE(url,
   393                                             query_params=query_params,
   394                                             headers=headers,
   395                                             _preload_content=_preload_content,
   396                                             _request_timeout=_request_timeout,
   397                                             body=body)
   398          else:
   399              raise ValueError(
   400                  "http method must be `GET`, `HEAD`, `OPTIONS`,"
   401                  " `POST`, `PATCH`, `PUT` or `DELETE`."
   402              )
   403  
   404      def parameters_to_tuples(self, params, collection_formats):
   405          """Get parameters as list of tuples, formatting collections.
   406  
   407          :param params: Parameters as dict or list of two-tuples
   408          :param dict collection_formats: Parameter collection formats
   409          :return: Parameters as list of tuples, collections formatted
   410          """
   411          new_params = []
   412          if collection_formats is None:
   413              collection_formats = {}
   414          for k, v in six.iteritems(params) if isinstance(params, dict) else params:  # noqa: E501
   415              if k in collection_formats:
   416                  collection_format = collection_formats[k]
   417                  if collection_format == 'multi':
   418                      new_params.extend((k, value) for value in v)
   419                  else:
   420                      if collection_format == 'ssv':
   421                          delimiter = ' '
   422                      elif collection_format == 'tsv':
   423                          delimiter = '\t'
   424                      elif collection_format == 'pipes':
   425                          delimiter = '|'
   426                      else:  # csv is the default
   427                          delimiter = ','
   428                      new_params.append(
   429                          (k, delimiter.join(str(value) for value in v)))
   430              else:
   431                  new_params.append((k, v))
   432          return new_params
   433  
   434      def prepare_post_parameters(self, post_params=None, files=None):
   435          """Builds form parameters.
   436  
   437          :param post_params: Normal form parameters.
   438          :param files: File parameters.
   439          :return: Form parameters with files.
   440          """
   441          params = []
   442  
   443          if post_params:
   444              params = post_params
   445  
   446          if files:
   447              for k, v in six.iteritems(files):
   448                  if not v:
   449                      continue
   450                  file_names = v if type(v) is list else [v]
   451                  for n in file_names:
   452                      with open(n, 'rb') as f:
   453                          filename = os.path.basename(f.name)
   454                          filedata = f.read()
   455                          mimetype = (mimetypes.guess_type(filename)[0] or
   456                                      'application/octet-stream')
   457                          params.append(
   458                              tuple([k, tuple([filename, filedata, mimetype])]))
   459  
   460          return params
   461  
   462      def select_header_accept(self, accepts):
   463          """Returns `Accept` based on an array of accepts provided.
   464  
   465          :param accepts: List of headers.
   466          :return: Accept (e.g. application/json).
   467          """
   468          if not accepts:
   469              return
   470  
   471          accepts = [x.lower() for x in accepts]
   472  
   473          if 'application/json' in accepts:
   474              return 'application/json'
   475          else:
   476              return ', '.join(accepts)
   477  
   478      def select_header_content_type(self, content_types):
   479          """Returns `Content-Type` based on an array of content_types provided.
   480  
   481          :param content_types: List of content-types.
   482          :return: Content-Type (e.g. application/json).
   483          """
   484          if not content_types:
   485              return 'application/json'
   486  
   487          content_types = [x.lower() for x in content_types]
   488  
   489          if 'application/json' in content_types or '*/*' in content_types:
   490              return 'application/json'
   491          else:
   492              return content_types[0]
   493  
   494      def update_params_for_auth(self, headers, querys, auth_settings):
   495          """Updates header and query params based on authentication setting.
   496  
   497          :param headers: Header parameters dict to be updated.
   498          :param querys: Query parameters tuple list to be updated.
   499          :param auth_settings: Authentication setting identifiers list.
   500          """
   501          if not auth_settings:
   502              return
   503  
   504          for auth in auth_settings:
   505              auth_setting = self.configuration.auth_settings().get(auth)
   506              if auth_setting:
   507                  if not auth_setting['value']:
   508                      continue
   509                  elif auth_setting['in'] == 'header':
   510                      headers[auth_setting['key']] = auth_setting['value']
   511                  elif auth_setting['in'] == 'query':
   512                      querys.append((auth_setting['key'], auth_setting['value']))
   513                  else:
   514                      raise ValueError(
   515                          'Authentication token must be in `query` or `header`'
   516                      )
   517  
   518      def __deserialize_file(self, response):
   519          """Deserializes body to file
   520  
   521          Saves response body into a file in a temporary folder,
   522          using the filename from the `Content-Disposition` header if provided.
   523  
   524          :param response:  RESTResponse.
   525          :return: file path.
   526          """
   527          fd, path = tempfile.mkstemp(dir=self.configuration.temp_folder_path)
   528          os.close(fd)
   529          os.remove(path)
   530  
   531          content_disposition = response.getheader("Content-Disposition")
   532          if content_disposition:
   533              filename = re.search(r'filename=[\'"]?([^\'"\s]+)[\'"]?',
   534                                   content_disposition).group(1)
   535              path = os.path.join(os.path.dirname(path), filename)
   536  
   537          with open(path, "w") as f:
   538              f.write(response.data)
   539  
   540          return path
   541  
   542      def __deserialize_primitive(self, data, klass):
   543          """Deserializes string to primitive type.
   544  
   545          :param data: str.
   546          :param klass: class literal.
   547  
   548          :return: int, long, float, str, bool.
   549          """
   550          try:
   551              return klass(data)
   552          except UnicodeEncodeError:
   553              return six.text_type(data)
   554          except TypeError:
   555              return data
   556  
   557      def __deserialize_object(self, value):
   558          """Return a original value.
   559  
   560          :return: object.
   561          """
   562          return value
   563  
   564      def __deserialize_date(self, string):
   565          """Deserializes string to date.
   566  
   567          :param string: str.
   568          :return: date.
   569          """
   570          try:
   571              from dateutil.parser import parse
   572              return parse(string).date()
   573          except ImportError:
   574              return string
   575          except ValueError:
   576              raise rest.ApiException(
   577                  status=0,
   578                  reason="Failed to parse `{0}` as date object".format(string)
   579              )
   580  
   581      def __deserialize_datatime(self, string):
   582          """Deserializes string to datetime.
   583  
   584          The string should be in iso8601 datetime format.
   585  
   586          :param string: str.
   587          :return: datetime.
   588          """
   589          try:
   590              from dateutil.parser import parse
   591              return parse(string)
   592          except ImportError:
   593              return string
   594          except ValueError:
   595              raise rest.ApiException(
   596                  status=0,
   597                  reason=(
   598                      "Failed to parse `{0}` as datetime object"
   599                      .format(string)
   600                  )
   601              )
   602  
   603      def __hasattr(self, object, name):
   604          return name in object.__class__.__dict__
   605  
   606      def __deserialize_model(self, data, klass):
   607          """Deserializes list or dict to model.
   608  
   609          :param data: dict, list.
   610          :param klass: class literal.
   611          :return: model object.
   612          """
   613  
   614          if (not klass.swagger_types and
   615                  not self.__hasattr(klass, 'get_real_child_model')):
   616              return data
   617  
   618          kwargs = {}
   619          if klass.swagger_types is not None:
   620              for attr, attr_type in six.iteritems(klass.swagger_types):
   621                  if (data is not None and
   622                          klass.attribute_map[attr] in data and
   623                          isinstance(data, (list, dict))):
   624                      value = data[klass.attribute_map[attr]]
   625                      kwargs[attr] = self.__deserialize(value, attr_type)
   626  
   627          instance = klass(**kwargs)
   628  
   629          if (isinstance(instance, dict) and
   630                  klass.swagger_types is not None and
   631                  isinstance(data, dict)):
   632              for key, value in data.items():
   633                  if key not in klass.swagger_types:
   634                      instance[key] = value
   635          if self.__hasattr(instance, 'get_real_child_model'):
   636              klass_name = instance.get_real_child_model(data)
   637              if klass_name:
   638                  instance = self.__deserialize(data, klass_name)
   639          return instance