Skip to content

Commit 4018a0f

Browse files
jacalatamarkm-iojorwoodsbcantoniBrian Cantoni
authored
v0.31 (#1378)
* Changes to alter cgi dependency to email.Messages * Changes to alter cgi dependency to email.Messages * Changes to alter cgi dependency to email.Messages * Changes to alter cgi dependency to email.Messages * feat: allow viz height and width parameters * fix: use python3.8 syntax * fix: python3.8 syntax * docs: comment PDF viz dimensions XOR * Add support for System schedule type I'm not fully clear on where these might come from, but this change should let TSC work in such cases. Fixes #1349 * Add failing test retrieving a task with 24 hour (aka daily) interval * Add 24 (hours) as a valid interval which can be returned from the server * Add Python 3.12 to test matrix * Tweak test action to stop double-running everything * feat: add description support on wb publish * Add Data Acceleration and Data Freshness Policy support (#1343) * Add data acceleration & data freshness policy functions * Add unit tests and raise errors on missing params * fix types & spell checks * addressed some feedback * addressed feedback * cleanup code * Revert "Merge branch 'add_data_acceleration_and_data_freshness_policy_support' of https://github.com/tableau/server-client-python into add_data_acceleration_and_data_freshness_policy_support" This reverts commit 5b30e57, reversing changes made to 5789e32. * fix formatting * Address feedback * mypy & formatting changes * Improve robustness of Pager results In some cases, Tableau Server might have a different between the advertised total number of object and the actual number returned via the Pager. This change adds one more check to prevent errors from happening in these situations. Fixes #1304 * Add Cloud Flow Task endpoint * cleanup * black format * add xml * edit test initialization * fix task initialization * third times the charm * cleanup * fix formatting * feat: pass parameters in request options * chore: pin typing_extensions version --------- Co-authored-by: markm <[email protected]> Co-authored-by: Mark Moreno <[email protected]> Co-authored-by: Jordan Woods <[email protected]> Co-authored-by: Brian Cantoni <[email protected]> Co-authored-by: Brian Cantoni <[email protected]> Co-authored-by: ltiffanydev <[email protected]> Co-authored-by: liu.r <[email protected]>
1 parent f84d7d5 commit 4018a0f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+1428
-38
lines changed

.github/workflows/run-tests.yml

+7-2
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
11
name: Python tests
22

3-
on: [push, pull_request]
3+
on:
4+
pull_request: {}
5+
push:
6+
branches:
7+
- development
8+
- master
49

510
jobs:
611
build:
712
strategy:
813
fail-fast: false
914
matrix:
1015
os: [ubuntu-latest, macos-latest, windows-latest]
11-
python-version: ['3.8', '3.9', '3.10', '3.11']
16+
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12']
1217

1318
runs-on: ${{ matrix.os }}
1419

pyproject.toml

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ dependencies = [
1616
'packaging>=23.1', # latest as at 7/31/23
1717
'requests>=2.31', # latest as at 7/31/23
1818
'urllib3==2.0.7', # latest as at 7/31/23
19+
'typing_extensions>=4.0.1',
1920
]
2021
requires-python = ">=3.7"
2122
classifiers = [
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
####
2+
# This script demonstrates how to update workbook data acceleration using the Tableau
3+
# Server Client.
4+
#
5+
# To run the script, you must have installed Python 3.7 or later.
6+
####
7+
8+
9+
import argparse
10+
import logging
11+
12+
import tableauserverclient as TSC
13+
from tableauserverclient import IntervalItem
14+
15+
16+
def main():
17+
parser = argparse.ArgumentParser(description="Creates sample schedules for each type of frequency.")
18+
# Common options; please keep those in sync across all samples
19+
parser.add_argument("--server", "-s", help="server address")
20+
parser.add_argument("--site", "-S", help="site name")
21+
parser.add_argument("--token-name", "-p", help="name of the personal access token used to sign into the server")
22+
parser.add_argument("--token-value", "-v", help="value of the personal access token used to sign into the server")
23+
parser.add_argument(
24+
"--logging-level",
25+
"-l",
26+
choices=["debug", "info", "error"],
27+
default="error",
28+
help="desired logging level (set to error by default)",
29+
)
30+
# Options specific to this sample:
31+
# This sample has no additional options, yet. If you add some, please add them here
32+
33+
args = parser.parse_args()
34+
35+
# Set logging level based on user input, or error by default
36+
logging_level = getattr(logging, args.logging_level.upper())
37+
logging.basicConfig(level=logging_level)
38+
39+
tableau_auth = TSC.PersonalAccessTokenAuth(args.token_name, args.token_value, site_id=args.site)
40+
server = TSC.Server(args.server, use_server_version=False)
41+
server.add_http_options({"verify": False})
42+
server.use_server_version()
43+
with server.auth.sign_in(tableau_auth):
44+
# Get workbook
45+
all_workbooks, pagination_item = server.workbooks.get()
46+
print("\nThere are {} workbooks on site: ".format(pagination_item.total_available))
47+
print([workbook.name for workbook in all_workbooks])
48+
49+
if all_workbooks:
50+
# Pick 1 workbook to try data acceleration.
51+
# Note that data acceleration has a couple of requirements, please check the Tableau help page
52+
# to verify your workbook/view is eligible for data acceleration.
53+
54+
# Assuming 1st workbook is eligible for sample purposes
55+
sample_workbook = all_workbooks[2]
56+
57+
# Enable acceleration for all the views in the workbook
58+
enable_config = dict()
59+
enable_config["acceleration_enabled"] = True
60+
enable_config["accelerate_now"] = True
61+
62+
sample_workbook.data_acceleration_config = enable_config
63+
updated: TSC.WorkbookItem = server.workbooks.update(sample_workbook)
64+
# Since we did not set any specific view, we will enable all views in the workbook
65+
print("Enable acceleration for all the views in the workbook " + updated.name + ".")
66+
67+
# Disable acceleration on one of the view in the workbook
68+
# You have to populate_views first, then set the views of the workbook
69+
# to the ones you want to update.
70+
server.workbooks.populate_views(sample_workbook)
71+
view_to_disable = sample_workbook.views[0]
72+
sample_workbook.views = [view_to_disable]
73+
74+
disable_config = dict()
75+
disable_config["acceleration_enabled"] = False
76+
disable_config["accelerate_now"] = True
77+
78+
sample_workbook.data_acceleration_config = disable_config
79+
# To get the acceleration status on the response, set includeViewAccelerationStatus=true
80+
# Note that you have to populate_views first to get the acceleration status, since
81+
# acceleration status is per view basis (not per workbook)
82+
updated: TSC.WorkbookItem = server.workbooks.update(sample_workbook, True)
83+
view1 = updated.views[0]
84+
print('Disabled acceleration for 1 view "' + view1.name + '" in the workbook ' + updated.name + ".")
85+
86+
# Get acceleration status of the views in workbook using workbooks.get_by_id
87+
# This won't need to do populate_views beforehand
88+
my_workbook = server.workbooks.get_by_id(sample_workbook.id)
89+
view1 = my_workbook.views[0]
90+
view2 = my_workbook.views[1]
91+
print(
92+
"Fetching acceleration status for views in the workbook "
93+
+ updated.name
94+
+ ".\n"
95+
+ 'View "'
96+
+ view1.name
97+
+ '" has acceleration_status = '
98+
+ view1.data_acceleration_config["acceleration_status"]
99+
+ ".\n"
100+
+ 'View "'
101+
+ view2.name
102+
+ '" has acceleration_status = '
103+
+ view2.data_acceleration_config["acceleration_status"]
104+
+ "."
105+
)
106+
107+
108+
if __name__ == "__main__":
109+
main()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,218 @@
1+
####
2+
# This script demonstrates how to update workbook data freshness policy using the Tableau
3+
# Server Client.
4+
#
5+
# To run the script, you must have installed Python 3.7 or later.
6+
####
7+
8+
9+
import argparse
10+
import logging
11+
12+
import tableauserverclient as TSC
13+
from tableauserverclient import IntervalItem
14+
15+
16+
def main():
17+
parser = argparse.ArgumentParser(description="Creates sample schedules for each type of frequency.")
18+
# Common options; please keep those in sync across all samples
19+
parser.add_argument("--server", "-s", help="server address")
20+
parser.add_argument("--site", "-S", help="site name")
21+
parser.add_argument("--token-name", "-p", help="name of the personal access token " "used to sign into the server")
22+
parser.add_argument(
23+
"--token-value", "-v", help="value of the personal access token " "used to sign into the server"
24+
)
25+
parser.add_argument(
26+
"--logging-level",
27+
"-l",
28+
choices=["debug", "info", "error"],
29+
default="error",
30+
help="desired logging level (set to error by default)",
31+
)
32+
# Options specific to this sample:
33+
# This sample has no additional options, yet. If you add some, please add them here
34+
35+
args = parser.parse_args()
36+
37+
# Set logging level based on user input, or error by default
38+
logging_level = getattr(logging, args.logging_level.upper())
39+
logging.basicConfig(level=logging_level)
40+
41+
tableau_auth = TSC.PersonalAccessTokenAuth(args.token_name, args.token_value, site_id=args.site)
42+
server = TSC.Server(args.server, use_server_version=False)
43+
server.add_http_options({"verify": False})
44+
server.use_server_version()
45+
with server.auth.sign_in(tableau_auth):
46+
# Get workbook
47+
all_workbooks, pagination_item = server.workbooks.get()
48+
print("\nThere are {} workbooks on site: ".format(pagination_item.total_available))
49+
print([workbook.name for workbook in all_workbooks])
50+
51+
if all_workbooks:
52+
# Pick 1 workbook that has live datasource connection.
53+
# Assuming 1st workbook met the criteria for sample purposes
54+
# Data Freshness Policy is not available on extract & file-based datasource.
55+
sample_workbook = all_workbooks[2]
56+
57+
# Get more info from the workbook selected
58+
# Troubleshoot: if sample_workbook_extended.data_freshness_policy.option returns with AttributeError
59+
# it could mean the workbook selected does not have live connection, which means it doesn't have
60+
# data freshness policy. Change to another workbook with live datasource connection.
61+
sample_workbook_extended = server.workbooks.get_by_id(sample_workbook.id)
62+
try:
63+
print(
64+
"Workbook "
65+
+ sample_workbook.name
66+
+ " has data freshness policy option set to: "
67+
+ sample_workbook_extended.data_freshness_policy.option
68+
)
69+
except AttributeError as e:
70+
print(
71+
"Workbook does not have data freshness policy, possibly due to the workbook selected "
72+
"does not have live connection. Change to another workbook using live datasource connection."
73+
)
74+
75+
# Update Workbook Data Freshness Policy to "AlwaysLive"
76+
sample_workbook.data_freshness_policy = TSC.DataFreshnessPolicyItem(
77+
TSC.DataFreshnessPolicyItem.Option.AlwaysLive
78+
)
79+
updated: TSC.WorkbookItem = server.workbooks.update(sample_workbook)
80+
print(
81+
"Workbook "
82+
+ updated.name
83+
+ " updated data freshness policy option to: "
84+
+ updated.data_freshness_policy.option
85+
)
86+
87+
# Update Workbook Data Freshness Policy to "SiteDefault"
88+
sample_workbook.data_freshness_policy = TSC.DataFreshnessPolicyItem(
89+
TSC.DataFreshnessPolicyItem.Option.SiteDefault
90+
)
91+
updated: TSC.WorkbookItem = server.workbooks.update(sample_workbook)
92+
print(
93+
"Workbook "
94+
+ updated.name
95+
+ " updated data freshness policy option to: "
96+
+ updated.data_freshness_policy.option
97+
)
98+
99+
# Update Workbook Data Freshness Policy to "FreshEvery" schedule.
100+
# Set the schedule to be fresh every 10 hours
101+
# Once the data_freshness_policy is already populated (e.g. due to previous calls),
102+
# it is possible to directly change the option & other parameters directly like below
103+
sample_workbook.data_freshness_policy.option = TSC.DataFreshnessPolicyItem.Option.FreshEvery
104+
fresh_every_ten_hours = TSC.DataFreshnessPolicyItem.FreshEvery(
105+
TSC.DataFreshnessPolicyItem.FreshEvery.Frequency.Hours, 10
106+
)
107+
sample_workbook.data_freshness_policy.fresh_every_schedule = fresh_every_ten_hours
108+
updated: TSC.WorkbookItem = server.workbooks.update(sample_workbook)
109+
print(
110+
"Workbook "
111+
+ updated.name
112+
+ " updated data freshness policy option to: "
113+
+ updated.data_freshness_policy.option
114+
+ " with frequency of "
115+
+ str(updated.data_freshness_policy.fresh_every_schedule.value)
116+
+ " "
117+
+ updated.data_freshness_policy.fresh_every_schedule.frequency
118+
)
119+
120+
# Update Workbook Data Freshness Policy to "FreshAt" schedule.
121+
# Set the schedule to be fresh at 10AM every day
122+
sample_workbook.data_freshness_policy.option = TSC.DataFreshnessPolicyItem.Option.FreshAt
123+
fresh_at_ten_daily = TSC.DataFreshnessPolicyItem.FreshAt(
124+
TSC.DataFreshnessPolicyItem.FreshAt.Frequency.Day, "10:00:00", "America/Los_Angeles"
125+
)
126+
sample_workbook.data_freshness_policy.fresh_at_schedule = fresh_at_ten_daily
127+
updated: TSC.WorkbookItem = server.workbooks.update(sample_workbook)
128+
print(
129+
"Workbook "
130+
+ updated.name
131+
+ " updated data freshness policy option to: "
132+
+ updated.data_freshness_policy.option
133+
+ " with frequency of "
134+
+ str(updated.data_freshness_policy.fresh_at_schedule.time)
135+
+ " every "
136+
+ updated.data_freshness_policy.fresh_at_schedule.frequency
137+
)
138+
139+
# Set the schedule to be fresh at 6PM every week on Wednesday and Sunday
140+
sample_workbook.data_freshness_policy = TSC.DataFreshnessPolicyItem(
141+
TSC.DataFreshnessPolicyItem.Option.FreshAt
142+
)
143+
fresh_at_6pm_wed_sun = TSC.DataFreshnessPolicyItem.FreshAt(
144+
TSC.DataFreshnessPolicyItem.FreshAt.Frequency.Week,
145+
"18:00:00",
146+
"America/Los_Angeles",
147+
[IntervalItem.Day.Wednesday, "Sunday"],
148+
)
149+
150+
sample_workbook.data_freshness_policy.fresh_at_schedule = fresh_at_6pm_wed_sun
151+
updated: TSC.WorkbookItem = server.workbooks.update(sample_workbook)
152+
new_fresh_at_schedule = updated.data_freshness_policy.fresh_at_schedule
153+
print(
154+
"Workbook "
155+
+ updated.name
156+
+ " updated data freshness policy option to: "
157+
+ updated.data_freshness_policy.option
158+
+ " with frequency of "
159+
+ str(new_fresh_at_schedule.time)
160+
+ " every "
161+
+ new_fresh_at_schedule.frequency
162+
+ " on "
163+
+ new_fresh_at_schedule.interval_item[0]
164+
+ ","
165+
+ new_fresh_at_schedule.interval_item[1]
166+
)
167+
168+
# Set the schedule to be fresh at 12AM every last day of the month
169+
sample_workbook.data_freshness_policy = TSC.DataFreshnessPolicyItem(
170+
TSC.DataFreshnessPolicyItem.Option.FreshAt
171+
)
172+
fresh_at_last_day_of_month = TSC.DataFreshnessPolicyItem.FreshAt(
173+
TSC.DataFreshnessPolicyItem.FreshAt.Frequency.Month, "00:00:00", "America/Los_Angeles", ["LastDay"]
174+
)
175+
176+
sample_workbook.data_freshness_policy.fresh_at_schedule = fresh_at_last_day_of_month
177+
updated: TSC.WorkbookItem = server.workbooks.update(sample_workbook)
178+
new_fresh_at_schedule = updated.data_freshness_policy.fresh_at_schedule
179+
print(
180+
"Workbook "
181+
+ updated.name
182+
+ " updated data freshness policy option to: "
183+
+ updated.data_freshness_policy.option
184+
+ " with frequency of "
185+
+ str(new_fresh_at_schedule.time)
186+
+ " every "
187+
+ new_fresh_at_schedule.frequency
188+
+ " on "
189+
+ new_fresh_at_schedule.interval_item[0]
190+
)
191+
192+
# Set the schedule to be fresh at 8PM every 1st,13th,20th day of the month
193+
fresh_at_dates_of_month = TSC.DataFreshnessPolicyItem.FreshAt(
194+
TSC.DataFreshnessPolicyItem.FreshAt.Frequency.Month,
195+
"00:00:00",
196+
"America/Los_Angeles",
197+
["1", "13", "20"],
198+
)
199+
200+
sample_workbook.data_freshness_policy.fresh_at_schedule = fresh_at_dates_of_month
201+
updated: TSC.WorkbookItem = server.workbooks.update(sample_workbook)
202+
new_fresh_at_schedule = updated.data_freshness_policy.fresh_at_schedule
203+
print(
204+
"Workbook "
205+
+ updated.name
206+
+ " updated data freshness policy option to: "
207+
+ updated.data_freshness_policy.option
208+
+ " with frequency of "
209+
+ str(new_fresh_at_schedule.time)
210+
+ " every "
211+
+ new_fresh_at_schedule.frequency
212+
+ " on "
213+
+ str(new_fresh_at_schedule.interval_item)
214+
)
215+
216+
217+
if __name__ == "__main__":
218+
main()

tableauserverclient/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
DailyInterval,
1111
DataAlertItem,
1212
DatabaseItem,
13+
DataFreshnessPolicyItem,
1314
DatasourceItem,
1415
FavoriteItem,
1516
FlowItem,

tableauserverclient/models/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from .data_acceleration_report_item import DataAccelerationReportItem
66
from .data_alert_item import DataAlertItem
77
from .database_item import DatabaseItem
8+
from .data_freshness_policy_item import DataFreshnessPolicyItem
89
from .datasource_item import DatasourceItem
910
from .dqw_item import DQWItem
1011
from .exceptions import UnpopulatedPropertyError

0 commit comments

Comments
 (0)