tableau / server-client-python

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

server.tasks.get() call does not properly handle interval of 24 for daily refresh tasks in Tableau Cloud #1354

Closed Maitredata closed 3 months ago

Maitredata commented 6 months ago

Describe the bug Basically, if we set up a daily refresh on Tableau Cloud, the Tableau Server Client receives an hourly interval of 24. We can see the value returned in Postman. However, according to the code (link below) the VALID_INTERVALS set does not contain 24 as a valid value.

Source: https://github.com/tableau/server-client-python/blob/master/tableauserverclient/models/interval_item.py#139 Line 139: # VALID_INTERVALS = {0.25, 0.5, 1, 2, 4, 6, 8, 12}

This results in a stack when a task has a daily recurrence, rather than a more frequent hourly

Versions

To Reproduce

  1. Log into your Tableau Cloud site
  2. Set up an extract refresh task on a Daily interval. Settings used from the configration are Repeats: Daily, Every: Day At: ANY, Days ANY
  3. Run script below (see sample code) to pull a server.tasks.get(), stack will occur.
  4. (Optional) check the equivelant call on Postman or another API, using the {{server}}/api/3.17/sites/{{site luid}}/tasks/extractRefreshes call and you'll see the expected value is 24, but the stack indicates the value is not part of the valid intervals set.

Results

Code run:

import tableauserverclient as TSC

siteID = ""
tokenName = ""
tokenSecret = ""

tableau_auth = TSC.PersonalAccessTokenAuth(tokenName, tokenSecret, siteID)
server = TSC.Server('', use_server_version=True)

with server.auth.sign_in(tableau_auth):
    tasksResponse = server.tasks.get()
    print(tasksResponse)

Here's the stack received:

Traceback (most recent call last):
  File "D:\Projects\CloudLoginTest.py", line 13, in <module>
    tasks, _ = server.tasks.get()
               ^^^^^^^^^^^^^^^^^^
  File "C:\Python312\Lib\site-packages\tableauserverclient\server\endpoint\endpoint.py", line 254, in wrapper
    return func(self, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Python312\Lib\site-packages\tableauserverclient\server\endpoint\tasks_endpoint.py", line 43, in get
    all_tasks = TaskItem.from_response(server_response.content, self.parent_srv.namespace, task_type)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Python312\Lib\site-packages\tableauserverclient\models\task_item.py", line 56, in from_response
    return list(all_tasks)
           ^^^^^^^^^^^^^^^
  File "C:\Python312\Lib\site-packages\tableauserverclient\models\task_item.py", line 54, in <genexpr>
    all_tasks = (TaskItem._parse_element(x, ns) for x in all_tasks_xml)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Python312\Lib\site-packages\tableauserverclient\models\task_item.py", line 67, in _parse_element
    schedule_item_list = ScheduleItem.from_element(element, ns)
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Python312\Lib\site-packages\tableauserverclient\models\schedule_item.py", line 222, in from_element
    ) = cls._parse_element(schedule_xml, ns)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Python312\Lib\site-packages\tableauserverclient\models\schedule_item.py", line 315, in _parse_element
    interval_item = ScheduleItem._parse_interval_item(frequency_detail_elem, frequency, ns)
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Python312\Lib\site-packages\tableauserverclient\models\schedule_item.py", line 269, in _parse_interval_item
    return DailyInterval(start_time, *converted_intervals)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Python312\Lib\site-packages\tableauserverclient\models\interval_item.py", line 114, in __init__
    self.interval = interval_values
    ^^^^^^^^^^^^^
  File "C:\Python312\Lib\site-packages\tableauserverclient\models\interval_item.py", line 150, in interval
    raise ValueError(error)
ValueError: Invalid interval 24.0 not in {0.25, 0.5, 2, 1, 4, 6, 8, 12}

Below is the output from the REST API call in Postman for my data source with a daily refresh task:

<?xml version='1.0' encoding='UTF-8'?>
<tsResponse xmlns="http://tableau.com/api" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://tableau.com/api https://help.tableau.com/samples/en-us/rest_api/ts-api_3_17.xsd">
    <tasks>
        <task>
            <extractRefresh id="996a77ba-cc8d-426c-94f6-a60e92ef5937" priority="50" consecutiveFailedCount="1" type="RefreshExtractTask">
                <schedule frequency="Daily" nextRunAt="2024-02-20T04:00:00Z">
                    <frequencyDetails start="20:00:00" end="20:00:00">
                        <intervals>
                            <interval hours="24"/>
                            <interval weekDay="Monday"/>
                        </intervals>
                    </frequencyDetails>
                </schedule>
                <datasource id="aa359870-03fc-43f1-ab13-de9b245ce354"/>
            </extractRefresh>
        </task>
        <task>
            <extractRefresh id="47162dba-5532-4c6a-bcd4-abc66fbce7a2" priority="50" consecutiveFailedCount="5" type="ExtractServiceFullRefreshExtractTask">
                <schedule frequency="Hourly" nextRunAt="2024-02-13T23:00:00Z">
                    <frequencyDetails start="09:00:00" end="19:00:00">
                        <intervals>
                            <interval hours="1"/>
                            <interval weekDay="Monday"/>
                            <interval weekDay="Tuesday"/>
                            <interval weekDay="Wednesday"/>
                            <interval weekDay="Thursday"/>
                            <interval weekDay="Friday"/>
                        </intervals>
                    </frequencyDetails>
                </schedule>
            </extractRefresh>
        </task>
    </tasks>
</tsResponse>

NOTE: Be careful not to post user names, passwords, auth tokens or any other private or sensitive information.

jacalata commented 3 months ago

fixed in https://github.com/tableau/server-client-python/pull/1355