Takes an array of bytes or a BufferedReader and uploads it. If async=false a json with the result is returned otherwise a json with an asset_id is returned.
    :param data: array of bytes or BufferedReader
    :param metadata: arbitrary additional description information for the asset
    :param async:
    :param callback: Callback URL
    :return:

def uploadAsset(self, data, async=False, metadata=None, callback=None):
    """Takes an array of bytes or a BufferedReader and uploads it. If async=false a json with the result is returned otherwise a json with an asset_id is returned.
    :param data: array of bytes or BufferedReader
    :param metadata: arbitrary additional description information for the asset
    :param async:
    :param callback: Callback URL
    :return:
    """
    #todo: has atter read would be better here
    if isinstance(data, io.BufferedReader):
      data = data.read()
    assert isinstance(data, bytes)
    data = base64.b64encode(data)
    audio = {'content': data.decode("utf-8")}
    config = {'async': async}
    if callback is not None:
      config['callback'] = callback

    if metadata is not None:
      body = {'audio': audio, 'config': config, 'metadata': metadata}
    else:
      body = {'audio': audio, 'config': config}

    return self._checkReturn(
      requests.post("{}/speech:recognize?signed_username={}".format(self.url, self.signedUsername), json=body))