Skip to content

Commit d169d9e

Browse files
committed
First run at internal pager
1 parent 01eca16 commit d169d9e

File tree

3 files changed

+48
-3
lines changed

3 files changed

+48
-3
lines changed

tableauserverclient/server/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,5 @@
88
from .endpoint import Auth, Datasources, Endpoint, Groups, Projects, Schedules, \
99
Sites, Users, Views, Workbooks, ServerResponseError, MissingRequiredFieldError
1010
from .server import Server
11-
from .pager import Pager
11+
from .pager import Pager, InternalPager
1212
from .exceptions import NotSignedInError

tableauserverclient/server/endpoint/groups_endpoint.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,22 @@ def get(self, req_options=None):
2525
# Gets all users in a given group
2626
@api(version="2.0")
2727
def populate_users(self, group_item, req_options=None):
28+
from .. import InternalPager
2829
if not group_item.id:
2930
error = "Group item missing ID. Group must be retrieved from server first."
3031
raise MissingRequiredFieldError(error)
32+
33+
all_users = InternalPager(self._get_users_for_group, group_item, request_opts=req_options)
34+
35+
group_item._set_users(list(all_users))
36+
37+
def _get_users_for_group(self, group_item, req_options=None):
3138
url = "{0}/{1}/users".format(self.baseurl, group_item.id)
3239
server_response = self.get_request(url, req_options)
33-
group_item._set_users(UserItem.from_response(server_response.content))
40+
user_item = UserItem.from_response(server_response.content)
3441
pagination_item = PaginationItem.from_response(server_response.content)
3542
logger.info('Populated users for group (ID: {0})'.format(group_item.id))
36-
return pagination_item
43+
return user_item, pagination_item
3744

3845
# Deletes 1 group by id
3946
@api(version="2.0")

tableauserverclient/server/pager.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,41 @@ def _load_next_page(self, last_pagination_item):
4141
opts.sort, opts.filter = self._options.sort, self._options.filter
4242
current_item_list, last_pagination_item = self._endpoint(opts)
4343
return current_item_list, last_pagination_item
44+
45+
class InternalPager(object):
46+
47+
def __init__(self, caller, *args, request_opts=None, **kwargs):
48+
self._endpoint = caller
49+
self._options = request_opts
50+
self._funcargs = args
51+
self._kwargs = kwargs
52+
# If we have options we could be starting on any page, backfill the count
53+
if self._options:
54+
self._count = ((self._options.pagenumber - 1) * self._options.pagesize)
55+
else:
56+
self._count = 0
57+
58+
def __iter__(self):
59+
# Fetch the first page
60+
current_item_list, last_pagination_item = self._endpoint(*self._funcargs, **self._kwargs, req_options=self._options)
61+
62+
# Get the rest on demand as a generator
63+
while self._count < last_pagination_item.total_available:
64+
if len(current_item_list) == 0:
65+
current_item_list, last_pagination_item = self._load_next_page(last_pagination_item)
66+
67+
try:
68+
yield current_item_list.pop(0)
69+
self._count += 1
70+
71+
except IndexError:
72+
# The total count on Server changed while fetching exit gracefully
73+
raise StopIteration
74+
75+
def _load_next_page(self, last_pagination_item):
76+
next_page = last_pagination_item.page_number + 1
77+
opts = RequestOptions(pagenumber=next_page, pagesize=last_pagination_item.page_size)
78+
if self._options is not None:
79+
opts.sort, opts.filter = self._options.sort, self._options.filter
80+
current_item_list, last_pagination_item = self._endpoint(*self._funcargs, **self._kwargs, req_options=opts)
81+
return current_item_list, last_pagination_item

0 commit comments

Comments
 (0)