From c0e924319a1aed5b1e0ea37224f1a6cb8a45c177 Mon Sep 17 00:00:00 2001 From: Russell Hay Date: Tue, 30 Jan 2018 14:30:42 -0800 Subject: [PATCH 1/6] Implement view filters on the populate* request options --- tableauserverclient/__init__.py | 2 +- tableauserverclient/server/__init__.py | 2 +- .../server/endpoint/views_endpoint.py | 2 +- tableauserverclient/server/request_options.py | 34 +++++++++++++++++-- 4 files changed, 34 insertions(+), 6 deletions(-) diff --git a/tableauserverclient/__init__.py b/tableauserverclient/__init__.py index c5840d7b6..30ec47981 100644 --- a/tableauserverclient/__init__.py +++ b/tableauserverclient/__init__.py @@ -4,7 +4,7 @@ SiteItem, TableauAuth, UserItem, ViewItem, WorkbookItem, UnpopulatedPropertyError, \ HourlyInterval, DailyInterval, WeeklyInterval, MonthlyInterval, IntervalItem, TaskItem, \ SubscriptionItem -from .server import RequestOptions, ImageRequestOptions, PDFRequestOptions, Filter, Sort, \ +from .server import RequestOptions, CSVRequestOptions, ImageRequestOptions, PDFRequestOptions, Filter, Sort, \ Server, ServerResponseError, MissingRequiredFieldError, NotSignedInError, Pager from ._version import get_versions __version__ = get_versions()['version'] diff --git a/tableauserverclient/server/__init__.py b/tableauserverclient/server/__init__.py index 12a640723..704fdb66a 100644 --- a/tableauserverclient/server/__init__.py +++ b/tableauserverclient/server/__init__.py @@ -1,5 +1,5 @@ from .request_factory import RequestFactory -from .request_options import ImageRequestOptions, PDFRequestOptions, RequestOptions +from .request_options import CSVRequestOptions, ImageRequestOptions, PDFRequestOptions, RequestOptions from .filter import Filter from .sort import Sort from .. import ConnectionItem, DatasourceItem, JobItem, \ diff --git a/tableauserverclient/server/endpoint/views_endpoint.py b/tableauserverclient/server/endpoint/views_endpoint.py index 0335ce781..072b68287 100644 --- a/tableauserverclient/server/endpoint/views_endpoint.py +++ b/tableauserverclient/server/endpoint/views_endpoint.py @@ -105,7 +105,7 @@ def csv_fetcher(): def _get_view_csv(self, view_item, req_options): url = "{0}/{1}/data".format(self.baseurl, view_item.id) - with closing(self.get_request(url, parameters={"stream": True})) as server_response: + with closing(self.get_request(url, req_options)) as server_response: csv = server_response.iter_content(1024) return csv diff --git a/tableauserverclient/server/request_options.py b/tableauserverclient/server/request_options.py index 37f23f54c..0e1119718 100644 --- a/tableauserverclient/server/request_options.py +++ b/tableauserverclient/server/request_options.py @@ -62,12 +62,36 @@ def apply_query_params(self, url): return "{0}?{1}".format(url, '&'.join(params)) -class ImageRequestOptions(RequestOptionsBase): +class _FilterOptionsBase(RequestOptionsBase): + def __init__(self): + self.view_filters = [] + + def apply_query_params(self, url): + raise NotImplementedError() + + def vf(self, name, value): + self.view_filters.append((name, value)) + return self + + def _append_view_filters(self, params): + for name, value in self.view_filters: + params.append('vf_{}={}'.format(name, value)) + + +class CSVRequestOptions(_FilterOptionsBase): + def apply_query_params(self, url): + params =['Stream=True'] + self._append_view_filters(params) + return "{0}?{1}".format(url, '&'.join(params)) + + +class ImageRequestOptions(_FilterOptionsBase): # if 'high' isn't specified, the REST API endpoint returns an image with standard resolution class Resolution: High = 'high' def __init__(self, imageresolution=None): + super(ImageRequestOptions, self).__init__() self.image_resolution = imageresolution def apply_query_params(self, url): @@ -75,11 +99,12 @@ def apply_query_params(self, url): if self.image_resolution: params.append('resolution={0}'.format(self.image_resolution)) + self._append_view_filters(params) + return "{0}?{1}".format(url, '&'.join(params)) -class PDFRequestOptions(RequestOptionsBase): - # if 'high' isn't specified, the REST API endpoint returns an image with standard resolution +class PDFRequestOptions(_FilterOptionsBase): class PageType: A3 = "a3" A4 = "a4" @@ -100,6 +125,7 @@ class Orientation: Landscape = "landscape" def __init__(self, page_type=None, orientation=None): + super(PDFRequestOptions, self).__init__() self.page_type = page_type self.orientation = orientation @@ -111,4 +137,6 @@ def apply_query_params(self, url): if self.orientation: params.append('orientation={0}'.format(self.orientation)) + self._append_view_filters(params) + return "{0}?{1}".format(url, '&'.join(params)) From 0bb7f9e0ad73077ce60a21bf3eaa4ce8155688c1 Mon Sep 17 00:00:00 2001 From: Russell Hay Date: Tue, 30 Jan 2018 14:35:33 -0800 Subject: [PATCH 2/6] pep8 fix --- tableauserverclient/server/request_options.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tableauserverclient/server/request_options.py b/tableauserverclient/server/request_options.py index 0e1119718..555923c9d 100644 --- a/tableauserverclient/server/request_options.py +++ b/tableauserverclient/server/request_options.py @@ -80,7 +80,7 @@ def _append_view_filters(self, params): class CSVRequestOptions(_FilterOptionsBase): def apply_query_params(self, url): - params =['Stream=True'] + params = ['Stream=True'] self._append_view_filters(params) return "{0}?{1}".format(url, '&'.join(params)) From 24313e88aec02bf92e9b240e9c91f4770a8d277b Mon Sep 17 00:00:00 2001 From: Russell Hay Date: Tue, 30 Jan 2018 16:23:51 -0800 Subject: [PATCH 3/6] Fix stream=true being passed to requests --- tableauserverclient/server/endpoint/views_endpoint.py | 2 +- tableauserverclient/server/request_options.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tableauserverclient/server/endpoint/views_endpoint.py b/tableauserverclient/server/endpoint/views_endpoint.py index 072b68287..ecba8355e 100644 --- a/tableauserverclient/server/endpoint/views_endpoint.py +++ b/tableauserverclient/server/endpoint/views_endpoint.py @@ -105,7 +105,7 @@ def csv_fetcher(): def _get_view_csv(self, view_item, req_options): url = "{0}/{1}/data".format(self.baseurl, view_item.id) - with closing(self.get_request(url, req_options)) as server_response: + with closing(self.get_request(url, req_options, {"s tream": True})) as server_response: csv = server_response.iter_content(1024) return csv diff --git a/tableauserverclient/server/request_options.py b/tableauserverclient/server/request_options.py index 555923c9d..c74fb125b 100644 --- a/tableauserverclient/server/request_options.py +++ b/tableauserverclient/server/request_options.py @@ -80,7 +80,7 @@ def _append_view_filters(self, params): class CSVRequestOptions(_FilterOptionsBase): def apply_query_params(self, url): - params = ['Stream=True'] + params = [] self._append_view_filters(params) return "{0}?{1}".format(url, '&'.join(params)) From 0e0622b00a29ef079467e86b6c6dcdfe56ca6452 Mon Sep 17 00:00:00 2001 From: Russell Hay Date: Tue, 30 Jan 2018 16:32:27 -0800 Subject: [PATCH 4/6] Fixing typo --- tableauserverclient/server/endpoint/views_endpoint.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tableauserverclient/server/endpoint/views_endpoint.py b/tableauserverclient/server/endpoint/views_endpoint.py index ecba8355e..bf1ae8995 100644 --- a/tableauserverclient/server/endpoint/views_endpoint.py +++ b/tableauserverclient/server/endpoint/views_endpoint.py @@ -105,7 +105,7 @@ def csv_fetcher(): def _get_view_csv(self, view_item, req_options): url = "{0}/{1}/data".format(self.baseurl, view_item.id) - with closing(self.get_request(url, req_options, {"s tream": True})) as server_response: + with closing(self.get_request(url, req_options, {"stream": True})) as server_response: csv = server_response.iter_content(1024) return csv From 098a8573ff0941d111ffe0b111b8809e7b8c9411 Mon Sep 17 00:00:00 2001 From: Russell Hay Date: Wed, 31 Jan 2018 14:04:31 -0800 Subject: [PATCH 5/6] Addressing Tyler's Feedback --- tableauserverclient/server/endpoint/views_endpoint.py | 3 ++- tableauserverclient/server/request_options.py | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/tableauserverclient/server/endpoint/views_endpoint.py b/tableauserverclient/server/endpoint/views_endpoint.py index bf1ae8995..4055ba2a9 100644 --- a/tableauserverclient/server/endpoint/views_endpoint.py +++ b/tableauserverclient/server/endpoint/views_endpoint.py @@ -105,7 +105,8 @@ def csv_fetcher(): def _get_view_csv(self, view_item, req_options): url = "{0}/{1}/data".format(self.baseurl, view_item.id) - with closing(self.get_request(url, req_options, {"stream": True})) as server_response: + with closing(self.get_request(url, + reqquest_object=req_options, parameters={"stream": True})) as server_response: csv = server_response.iter_content(1024) return csv diff --git a/tableauserverclient/server/request_options.py b/tableauserverclient/server/request_options.py index c74fb125b..b7d5c591d 100644 --- a/tableauserverclient/server/request_options.py +++ b/tableauserverclient/server/request_options.py @@ -63,6 +63,7 @@ def apply_query_params(self, url): class _FilterOptionsBase(RequestOptionsBase): + """ Provide a basic implementation of adding view filters to the url """ def __init__(self): self.view_filters = [] From a01dd4b66cc9cce0ae386d1ce9669ce13ad41b94 Mon Sep 17 00:00:00 2001 From: Russell Hay Date: Wed, 31 Jan 2018 14:08:31 -0800 Subject: [PATCH 6/6] typo --- tableauserverclient/server/endpoint/views_endpoint.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tableauserverclient/server/endpoint/views_endpoint.py b/tableauserverclient/server/endpoint/views_endpoint.py index 4055ba2a9..62cd3af50 100644 --- a/tableauserverclient/server/endpoint/views_endpoint.py +++ b/tableauserverclient/server/endpoint/views_endpoint.py @@ -105,8 +105,7 @@ def csv_fetcher(): def _get_view_csv(self, view_item, req_options): url = "{0}/{1}/data".format(self.baseurl, view_item.id) - with closing(self.get_request(url, - reqquest_object=req_options, parameters={"stream": True})) as server_response: + with closing(self.get_request(url, request_object=req_options, parameters={"stream": True})) as server_response: csv = server_response.iter_content(1024) return csv