docs: def call(self, func, *api_args, **api_kwargs):
          """Send API call to SDK server and return results"""
          if not isinstance(func, str) or (func == ''):
              msg = ('Invalid input for API name, should be a'
                     'string, type: %s specified.') % type(func)
              return self._construct_api_name_error(msg)
  
          # Create client socket
          try:
              cs = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
          except socket.error as err:
              return self._construct_socket_error(1, error=six.text_type(err))
  
          try:
              # Set socket timeout
              cs.settimeout(self.timeout)
              # Connect SDK server
              try:
                  cs.connect((self.addr, self.port))
              except socket.error as err:
                  return self._construct_socket_error(2, addr=self.addr,
                                                      port=self.port,
                                                      error=six.text_type(err))
  
              # Prepare the data to be sent and switch to bytes if needed
              api_data = json.dumps((func, api_args, api_kwargs))
              api_data = api_data.encode()
  
              # Send the API call data to SDK server
              sent = 0
              total_len = len(api_data)
              got_error = False
              try:
                  while (sent < total_len):
                      this_sent = cs.send(api_data[sent:])
                      if this_sent == 0:
                          got_error = True
                          break
                      sent += this_sent
              except socket.error as err:
                  return self._construct_socket_error(5,
                                                      error=six.text_type(err))
  
              if got_error or sent != total_len:
                  return self._construct_socket_error(3, sent=sent,
                                                      api=api_data)
  
              # Receive data from server
              return_blocks = []
              try:
                  while True:
                      block = cs.recv(4096)
                      if not block:
                          break
                      block = bytes.decode(block)
                      return_blocks.append(block)
              except socket.error as err:
                  # When the sdkserver cann't handle all the client request,
                  # some client request would be rejected.
                  # Under this case, the client socket can successfully
                  # connect/send, but would get exception in recv with error:
                  # "error: [Errno 104] Connection reset by peer"
                  return self._construct_socket_error(6,
                                                      error=six.text_type(err))
          finally:
              # Always close the client socket to avoid too many hanging
              # socket left.
              cs.close()
  
          # Transform the received stream to standard result form
          # This client assumes that the server would return result in
          # the standard result form, so client just return the received
          # data
          if return_blocks:
              results = json.loads(''.join(return_blocks))
          else:
              results = self._construct_socket_error(4)
          return results