From 81b49205ecda703428dae82b99de94eba9b0b63f Mon Sep 17 00:00:00 2001 From: Russell Hay Date: Fri, 21 Oct 2016 09:48:44 -0700 Subject: [PATCH 1/4] Adding pagination sample --- samples/pagination_sample.py | 78 ++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 samples/pagination_sample.py diff --git a/samples/pagination_sample.py b/samples/pagination_sample.py new file mode 100644 index 000000000..e29269867 --- /dev/null +++ b/samples/pagination_sample.py @@ -0,0 +1,78 @@ +#### +# This script demonstrates how to use pagination item that is returned as part +# of mayn of the .get() method calls. +# +# This script will iterate over every workbook that exists on the server using the +# pagination item to fetch additional pages as needed. +# +# While this sample uses workbook, this same technique will work with any of the .get() methods that return +# a pagination item +#### + +import argparse +import getpass +import logging +import os.path + +import tableauserverclient as TSC + +class pagination_generator(object): + """ This class returns a generator that will iterate over all of the results. + + server is the server object that will be used when calling the callback. It will be passed + to the callback on each iteration + + Callback is expected to take a server object and a request options and return two values, an array of results, and the pagination item + from the current call. This will be used to build subsequent requests. + """ + + def __init__(self, server, callback): + self._server = server + self._callback = callback + + def __call__(self): + current_item_list, last_pagination_item = self._callback(self._server, None) # Prime the generator + count = 0 + + while count < last_pagination_item.total_available: + if len(current_item_list) == 0: + current_item_list, last_pagination_item = self._load_next_page(current_item_list, last_pagination_item) + + yield current_item_list.pop(0) + count += 1 + + def _load_next_page(self, current_item_list, last_pagination_item): + next_page = last_pagination_item.page_number + 1 + opts = TSC.RequestOptions(pagenumber=next_page, pagesize=last_pagination_item.page_size) + current_item_list, last_pagination_item = self._callback(self._server, opts) + return current_item_list, last_pagination_item + + +def main(): + + parser = argparse.ArgumentParser(description='Explore workbook functions supported by the Server API.') + parser.add_argument('--server', '-s', required=True, help='server address') + parser.add_argument('--username', '-u', required=True, help='username to sign into server') + parser.add_argument('--logging-level', '-l', choices=['debug', 'info', 'error'], default='error', + help='desired logging level (set to error by default)') + + args = parser.parse_args() + + password = getpass.getpass("Password: ") + + # Set logging level based on user input, or error by default + logging_level = getattr(logging, args.logging_level.upper()) + logging.basicConfig(level=logging_level) + + # SIGN IN + tableau_auth = TSC.TableauAuth(args.username, password) + server = TSC.Server(args.server) + + with server.auth.sign_in(tableau_auth): + generator = pagination_generator(server, lambda srv, opts: srv.workbooks.get(req_options=opts)) + print("Your server contains the following workbooks:\n") + for wb in generator(): + print(wb.name) + +if __name__ == '__main__': + main() From 742c25e008f41f819edb0ebc557fc65bb304c625 Mon Sep 17 00:00:00 2001 From: Russell Hay Date: Fri, 21 Oct 2016 10:00:22 -0700 Subject: [PATCH 2/4] pep8 fixes --- samples/pagination_sample.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/samples/pagination_sample.py b/samples/pagination_sample.py index e29269867..887e49c88 100644 --- a/samples/pagination_sample.py +++ b/samples/pagination_sample.py @@ -16,14 +16,15 @@ import tableauserverclient as TSC + class pagination_generator(object): """ This class returns a generator that will iterate over all of the results. server is the server object that will be used when calling the callback. It will be passed to the callback on each iteration - Callback is expected to take a server object and a request options and return two values, an array of results, and the pagination item - from the current call. This will be used to build subsequent requests. + Callback is expected to take a server object and a request options and return two values, an array of results, + and the pagination item from the current call. This will be used to build subsequent requests. """ def __init__(self, server, callback): From c71013f01c9afbfd38c2d53758e46002d6f7a831 Mon Sep 17 00:00:00 2001 From: Russell Hay Date: Fri, 21 Oct 2016 10:12:13 -0700 Subject: [PATCH 3/4] Ben's feedback incorporated --- samples/pagination_sample.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/samples/pagination_sample.py b/samples/pagination_sample.py index 887e49c88..dc5686d1d 100644 --- a/samples/pagination_sample.py +++ b/samples/pagination_sample.py @@ -1,6 +1,6 @@ #### # This script demonstrates how to use pagination item that is returned as part -# of mayn of the .get() method calls. +# of many of the .get() method calls. # # This script will iterate over every workbook that exists on the server using the # pagination item to fetch additional pages as needed. @@ -51,7 +51,7 @@ def _load_next_page(self, current_item_list, last_pagination_item): def main(): - parser = argparse.ArgumentParser(description='Explore workbook functions supported by the Server API.') + parser = argparse.ArgumentParser(description='Return a list of all of the workbooks on your server') parser.add_argument('--server', '-s', required=True, help='server address') parser.add_argument('--username', '-u', required=True, help='username to sign into server') parser.add_argument('--logging-level', '-l', choices=['debug', 'info', 'error'], default='error', From 5f8ba95419c8fe7f4276ef93a45836e3c00108b8 Mon Sep 17 00:00:00 2001 From: Russell Hay Date: Fri, 21 Oct 2016 13:54:35 -0700 Subject: [PATCH 4/4] Simplifying usage by eliminating the lambda --- samples/pagination_sample.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/samples/pagination_sample.py b/samples/pagination_sample.py index dc5686d1d..7bc5b8dcc 100644 --- a/samples/pagination_sample.py +++ b/samples/pagination_sample.py @@ -27,12 +27,11 @@ class pagination_generator(object): and the pagination item from the current call. This will be used to build subsequent requests. """ - def __init__(self, server, callback): - self._server = server - self._callback = callback + def __init__(self, fetch_more): + self._fetch_more = fetch_more def __call__(self): - current_item_list, last_pagination_item = self._callback(self._server, None) # Prime the generator + current_item_list, last_pagination_item = self._fetch_more(None) # Prime the generator count = 0 while count < last_pagination_item.total_available: @@ -45,7 +44,7 @@ def __call__(self): def _load_next_page(self, current_item_list, last_pagination_item): next_page = last_pagination_item.page_number + 1 opts = TSC.RequestOptions(pagenumber=next_page, pagesize=last_pagination_item.page_size) - current_item_list, last_pagination_item = self._callback(self._server, opts) + current_item_list, last_pagination_item = self._fetch_more(opts) return current_item_list, last_pagination_item @@ -66,11 +65,12 @@ def main(): logging.basicConfig(level=logging_level) # SIGN IN + tableau_auth = TSC.TableauAuth(args.username, password) server = TSC.Server(args.server) with server.auth.sign_in(tableau_auth): - generator = pagination_generator(server, lambda srv, opts: srv.workbooks.get(req_options=opts)) + generator = pagination_generator(server.workbooks.get) print("Your server contains the following workbooks:\n") for wb in generator(): print(wb.name)