Skip to content

TSC.Pager() with default options returns invalid page number #1304

Closed

Description

@CodingOnWindowsOS

Describe the bug
When using TSC.Pager() to retrieve all subscriptions on the Tableau site, invalid page number is returned. When the error is ignored, server.subscriptions returns 400 subscription items when there are 409.

If it helps, this functionality was working as late as 08/29/2023.

Versions
Tableau Server version: 2022.1
Python version: Python 3.9.12
TSC Version: 3.15
Library version: 0.28

To Reproduce

import tableauserverclient as tsc

token_name = 'some_token_name'
token_value = 'some_token_value'
tableau_auth = tsc.PersonalAccessTokenAuth(token_name=token_name, personal_access_token=token_value)
server = tsc.Server('some_server')
server.add_http_options({'verify': False})

with server.auth.sign_in(tableau_auth):
    # Ensure the most recent Tableau REST API version is used.
    server.use_highest_version()
    # Gather all subscriptions.
    subscriptions = [subscription for subscription in tsc.Pager(server.subscriptions)]

Results
What are the results or error messages received?

ServerResponseError: 

	400006: Bad Request
		Invalid page number '5'

Activity

  1. JStooke commented on Dec 13, 2023

    @JStooke

    Ran in to the same issue. In my case it was when using the server.groups.populate_users running against a large group.

    It seems like sometimes there are less items returned by the pager than the expected "total_available". Could be down to changes in membership while pager is running but i've also found a group that consistently returns one less member than total_available suggests.

    So in my example total_available states 3706, but actual number returned from pager is 3705, the pager logic sees no more items in page, but more still to get, so attempts to pull the next page and fails as it doesn't exist.

    Ended up adding a check here:

    if len(current_item_list) == 0:

    To make sure it only retrieves a new page if the (current page number*page size) is less than total_available

            # Get the rest on demand as a generator
    
            while self._count < last_pagination_item.total_available:
                if len(current_item_list) == 0 and last_pagination_item.page_number*last_pagination_item.page_size < last_pagination_item.total_available:
                    current_item_list, last_pagination_item = self._load_next_page(last_pagination_item)
    
                try:
                    yield current_item_list.pop(0)
                    self._count += 1
    
                except IndexError:
                    # The total count on Server changed while fetching exit gracefully
                    return

    This then fails the next pop attempt and raises the IndexError that is already exited from gracefully.

    This got it working locally but it'd be good to have this possibility handled in source.

  2. TrimPeachu commented on Jan 25, 2024

    @TrimPeachu
    Contributor

    Can confirm that @JStooke's fix worked for me as well in preventing the 'Invalid page number' error.
    In my case, however I was able to detect that root of problem was Tableau itself, as the group for which the code failed contained one person twice. It was showing in Tabelau as 100 users, same in the library, 100 as total_available but was only able to retrieve 99 and then failed. Removing the user from group and reinstating them fixed the issue on my end.

  3. added a commit that references this issue on Apr 27, 2024
    114214b
  4. added a commit that references this issue on Jun 3, 2024
    4018a0f
  5. added 2 commits that reference this issue on May 5, 2026
    97f6e62
    dc6b881
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions