tableau / server-client-python

A Python library for the Tableau Server REST API
https://tableau.github.io/server-client-python/
MIT License
657 stars 422 forks source link

Add option to return bytes stream to workbooks.download() method #811

Open YevhenKv opened 3 years ago

YevhenKv commented 3 years ago

Hi,

It would be nice if workbooks.download() method could also return bytes stream for downloaded object. For example, add argument stream=True/False to download function that would define whether object should be downloaded into specified path or returned as a byte stream. https://github.com/tableau/server-client-python/blob/master/tableauserverclient/server/endpoint/workbooks_endpoint.py#L134 In this case byte stream can be handled outside of library, for example it can be used to write data in AWS S3 bucket, GCS bucket or Azure Blob storage instead of local storage.

Example: def download(self, workbook_id, filepath=None, include_extract=True, no_extract=None, stream=False): if not workbook_id: error = "Workbook ID undefined." raise ValueError(error) url = "{0}/{1}/content".format(self.baseurl, workbook_id)

if no_extract is False or no_extract is True:
    import warnings
    warnings.warn('no_extract is deprecated, use include_extract instead.', DeprecationWarning)
    include_extract = not no_extract

if not include_extract:
    url += "?includeExtract=False"

with closing(self.get_request(url, parameters={"stream": True})) as server_response:
    _, params = cgi.parse_header(server_response.headers['Content-Disposition'])
    filename = to_filename(os.path.basename(params['filename']))
    if filepath:
        download_path = make_download_path(filepath, filename)

        with open(download_path, 'wb') as f:
            for chunk in server_response.iter_content(1024):  # 1KB
                f.write(chunk)
        logger.info('Downloaded workbook to {0} (ID: {1})'.format(download_path, workbook_id))
        return os.path.abspath(download_path)
    if stream:
        return server_response.content
SandervandenOord commented 2 years ago

Agree, now I first have to write to disk and then write to a cloud storage bucket