Skip to content

Commit 341dcd2

Browse files
jacalatama7tcspLarsBreddemannjorwoodsAustin
authored
0.27 (#1272)
* fix: TableauIDWithMFA added to the user_item model to allow creating users on Tableau Cloud with MFA enabled (#1216) * fix: make project optional in datasources #1210 * fix: allow setting timeout on workbook endpoint #1087 * fix: can't certify datasource on publish #1058 * fix filter in operator spaces bug (#1259) * fix: remove logging configuration from TSC (#1248) * Hotfix schedule_item.py for issue 1237 (#1239), Remove duplicate assignments to fields (#1244) * Fix shared attribute for custom views (#1280) New functionality * enable filtering for Excel downloads #1209, #1281 * query view by content url #456 * update datasource to use bridge (#1224) * Add JWTAuth, add repr using qualname * Add publish samples attribute (#1264) * add support for custom schedules in TOL (#1273) * Enable asJob for group update (#1276) Co-authored-by: Tim Payne <[email protected]> Co-authored-by: Lars Breddemann <[email protected]> Co-authored-by: jorwoods <[email protected]> Co-authored-by: Austin <[email protected]> Co-authored-by: Yasuhisa Yoshida <[email protected]> Co-authored-by: Brian Cantoni <[email protected]> Co-authored-by: a-torres-2 <[email protected]> Co-authored-by: Łukasz Włodarczyk <[email protected]>
1 parent 307d8a2 commit 341dcd2

36 files changed

+541
-57
lines changed

.github/workflows/code-coverage.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@ jobs:
1616
runs-on: ${{ matrix.os }}
1717

1818
steps:
19-
- uses: actions/checkout@v2
19+
- uses: actions/checkout@v3
2020

2121
- name: Set up Python ${{ matrix.python-version }} on ${{ matrix.os }}
22-
uses: actions/setup-python@v2
22+
uses: actions/setup-python@v4
2323
with:
2424
python-version: ${{ matrix.python-version }}
2525

.github/workflows/meta-checks.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@ jobs:
1313
runs-on: ${{ matrix.os }}
1414

1515
steps:
16-
- uses: actions/checkout@v2
16+
- uses: actions/checkout@v3
1717

1818
- name: Set up Python ${{ matrix.python-version }} on ${{ matrix.os }}
19-
uses: actions/setup-python@v2
19+
uses: actions/setup-python@v4
2020
with:
2121
python-version: ${{ matrix.python-version }}
2222

.github/workflows/publish-pypi.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ jobs:
1717
- uses: actions/checkout@v3
1818
with:
1919
fetch-depth: 0
20-
- uses: actions/setup-python@v1
20+
- uses: actions/setup-python@v4
2121
with:
2222
python-version: 3.7
2323
- name: Build dist files

.github/workflows/run-tests.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,15 @@ jobs:
88
fail-fast: false
99
matrix:
1010
os: [ubuntu-latest, macos-latest, windows-latest]
11-
python-version: ['3.7', '3.8', '3.9', '3.10']
11+
python-version: ['3.8', '3.9', '3.10', '3.11']
1212

1313
runs-on: ${{ matrix.os }}
1414

1515
steps:
16-
- uses: actions/checkout@v2
16+
- uses: actions/checkout@v3
1717

1818
- name: Set up Python ${{ matrix.python-version }} on ${{ matrix.os }}
19-
uses: actions/setup-python@v2
19+
uses: actions/setup-python@v4
2020
with:
2121
python-version: ${{ matrix.python-version }}
2222

@@ -33,4 +33,4 @@ jobs:
3333
- name: Test build
3434
if: always()
3535
run: |
36-
python -m build
36+
python -m build

pyproject.toml

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[build-system]
2-
requires = ["setuptools>=45.0", "versioneer>=0.24", "wheel"]
2+
requires = ["setuptools>=68.0", "versioneer>=0.29", "wheel"]
33
build-backend = "setuptools.build_meta"
44

55
[project]
@@ -12,39 +12,41 @@ license = {file = "LICENSE"}
1212
readme = "README.md"
1313

1414
dependencies = [
15-
'defusedxml>=0.7.1',
16-
'packaging>=22.0', # bumping to minimum version required by black
17-
'requests>=2.28',
18-
'urllib3~=1.26.8',
15+
'defusedxml>=0.7.1', # latest as at 7/31/23
16+
'packaging>=23.1', # latest as at 7/31/23
17+
'requests>=2.31', # latest as at 7/31/23
18+
'urllib3==2.0.4', # latest as at 7/31/23
1919
]
2020
requires-python = ">=3.7"
2121
classifiers = [
2222
"Programming Language :: Python",
2323
"Programming Language :: Python :: 3",
24-
"Programming Language :: Python :: 3.7",
2524
"Programming Language :: Python :: 3.8",
2625
"Programming Language :: Python :: 3.9",
27-
"Programming Language :: Python :: 3.10"
26+
"Programming Language :: Python :: 3.10",
27+
"Programming Language :: Python :: 3.11",
28+
"Programming Language :: Python :: 3.12"
2829
]
2930
[project.urls]
3031
repository = "https://github.com/tableau/server-client-python"
3132

3233
[project.optional-dependencies]
33-
test = ["argparse", "black", "mock", "mypy", "pytest>=7.0", "pytest-subtests", "requests-mock>=1.0,<2.0"]
34+
test = ["argparse", "black==23.7", "mock", "mypy==1.4", "pytest>=7.0", "pytest-subtests", "requests-mock>=1.0,<2.0"]
3435

3536
[tool.black]
3637
line-length = 120
37-
target-version = ['py37', 'py38', 'py39', 'py310']
38+
target-version = ['py37', 'py38', 'py39', 'py310', 'py311', 'py312']
3839

3940
[tool.mypy]
41+
check_untyped_defs = false
4042
disable_error_code = [
4143
'misc',
42-
'import'
44+
# tableauserverclient\server\endpoint\datasources_endpoint.py:48: error: Cannot assign multiple types to name "FilePath" without an explicit "Type[...]" annotation [misc]
45+
'annotation-unchecked' # can be removed when check_untyped_defs = true
4346
]
4447
files = ["tableauserverclient", "test"]
4548
show_error_codes = true
46-
ignore_missing_imports = true
47-
49+
ignore_missing_imports = true # defusedxml library has no types
4850
[tool.pytest.ini_options]
4951
testpaths = ["test"]
5052
addopts = "--junitxml=./test.junit.xml"

samples/create_extract_task.py

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
####
2+
# This script demonstrates how to create extract tasks in Tableau Cloud
3+
# using the Tableau 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+
from datetime import time
13+
14+
import tableauserverclient as TSC
15+
16+
17+
def main():
18+
parser = argparse.ArgumentParser(description="Creates sample extract refresh task.")
19+
# Common options; please keep those in sync across all samples
20+
parser.add_argument("--server", "-s", help="server address")
21+
parser.add_argument("--site", "-S", help="site name")
22+
parser.add_argument("--token-name", "-p", help="name of the personal access token used to sign into the server")
23+
parser.add_argument("--token-value", "-v", help="value of the personal access token used to sign into the server")
24+
parser.add_argument(
25+
"--logging-level",
26+
"-l",
27+
choices=["debug", "info", "error"],
28+
default="error",
29+
help="desired logging level (set to error by default)",
30+
)
31+
# Options specific to this sample:
32+
# This sample has no additional options, yet. If you add some, please add them here
33+
34+
args = parser.parse_args()
35+
36+
# Set logging level based on user input, or error by default
37+
logging_level = getattr(logging, args.logging_level.upper())
38+
logging.basicConfig(level=logging_level)
39+
40+
tableau_auth = TSC.PersonalAccessTokenAuth(args.token_name, args.token_value, site_id=args.site)
41+
server = TSC.Server(args.server, use_server_version=False)
42+
server.add_http_options({"verify": False})
43+
server.use_server_version()
44+
with server.auth.sign_in(tableau_auth):
45+
# Monthly Schedule
46+
# This schedule will run on the 15th of every month at 11:30PM
47+
monthly_interval = TSC.MonthlyInterval(start_time=time(23, 30), interval_value=15)
48+
monthly_schedule = TSC.ScheduleItem(
49+
None,
50+
None,
51+
None,
52+
None,
53+
monthly_interval,
54+
)
55+
56+
# Default to using first workbook found in server
57+
all_workbook_items, pagination_item = server.workbooks.get()
58+
my_workbook: TSC.WorkbookItem = all_workbook_items[0]
59+
60+
target_item = TSC.Target(
61+
my_workbook.id, # the id of the workbook or datasource
62+
"workbook", # alternatively can be "datasource"
63+
)
64+
65+
extract_item = TSC.TaskItem(
66+
None,
67+
"FullRefresh",
68+
None,
69+
None,
70+
None,
71+
monthly_schedule,
72+
None,
73+
target_item,
74+
)
75+
76+
try:
77+
response = server.tasks.create(extract_item)
78+
print(response)
79+
except Exception as e:
80+
print(e)
81+
82+
83+
if __name__ == "__main__":
84+
main()

samples/create_project.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,14 @@ def main():
5757
server.use_server_version()
5858

5959
# Without parent_id specified, projects are created at the top level.
60-
top_level_project = TSC.ProjectItem(name="Top Level Project")
60+
# With the publish-samples attribute, the project will be created with sample items
61+
top_level_project = TSC.ProjectItem(
62+
name="Top Level Project",
63+
description="A sample tsc project",
64+
content_permissions=None,
65+
parent_id=None,
66+
samples=True,
67+
)
6168
top_level_project = create_project(server, top_level_project)
6269

6370
# Specifying parent_id creates a nested projects.

samples/explore_workbook.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ def main():
3636
parser.add_argument(
3737
"--preview-image", "-i", metavar="FILENAME", help="filename (a .png file) to save the preview image"
3838
)
39+
parser.add_argument(
40+
"--powerpoint", "-ppt", metavar="FILENAME", help="filename (a .ppt file) to save the powerpoint deck"
41+
)
3942

4043
args = parser.parse_args()
4144

@@ -145,6 +148,13 @@ def main():
145148
f.write(c.image)
146149
print("saved to " + filename)
147150

151+
if args.powerpoint:
152+
# Populate workbook preview image
153+
server.workbooks.populate_powerpoint(sample_workbook)
154+
with open(args.powerpoint, "wb") as f:
155+
f.write(sample_workbook.powerpoint)
156+
print("\nDownloaded powerpoint of workbook to {}".format(os.path.abspath(args.powerpoint)))
157+
148158
if args.delete:
149159
print("deleting {}".format(c.id))
150160
unlucky = TSC.CustomViewItem(c.id)
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
####
2+
# Getting started Part One of Three
3+
# This script demonstrates how to use the Tableau Server Client to connect to a server
4+
# You don't need to have a site or any experience with Tableau to run it
5+
#
6+
####
7+
8+
import tableauserverclient as TSC
9+
10+
11+
def main():
12+
# This is the domain for Tableau's Developer Program
13+
server_url = "https://10ax.online.tableau.com"
14+
server = TSC.Server(server_url)
15+
print("Connected to {}".format(server.server_info.baseurl))
16+
print("Server information: {}".format(server.server_info))
17+
print("Sign up for a test site at https://www.tableau.com/developer")
18+
19+
20+
if __name__ == "__main__":
21+
main()
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
####
2+
# Getting started Part Two of Three
3+
# This script demonstrates how to use the Tableau Server Client to
4+
# view the content on an existing site on Tableau Server/Online
5+
# It assumes that you have already got a site and can visit it in a browser
6+
#
7+
####
8+
9+
import getpass
10+
import tableauserverclient as TSC
11+
12+
13+
# 0 - launch your Tableau site in a web browser and look at the url to set the values below
14+
def main():
15+
# 1 - replace with your server domain: stop at the slash
16+
server_url = "https://10ax.online.tableau.com"
17+
18+
# 2 - optional - change to false **for testing only** if you get a certificate error
19+
use_ssl = True
20+
21+
server = TSC.Server(server_url, use_server_version=True, http_options={"verify": use_ssl})
22+
print("Connected to {}".format(server.server_info.baseurl))
23+
24+
# 3 - replace with your site name exactly as it looks in the url
25+
# e.g https://my-server/#/site/this-is-your-site-url-name/not-this-part
26+
site_url_name = "" # leave empty if there is no site name in the url (you are on the default site)
27+
28+
# 4 - replace with your username.
29+
# REMEMBER: if you are using Tableau Online, your username is the entire email address
30+
username = "your-username-here"
31+
password = getpass.getpass("Your password:") # so you don't save it in this file
32+
tableau_auth = TSC.TableauAuth(username, password, site_id=site_url_name)
33+
34+
# OR instead of username+password, uncomment this section to use a Personal Access Token
35+
# token_name = "your-token-name"
36+
# token_value = "your-token-value-long-random-string"
37+
# tableau_auth = TSC.PersonalAccessTokenAuth(token_name, token_value, site_id=site_url_name)
38+
39+
with server.auth.sign_in(tableau_auth):
40+
projects, pagination = server.projects.get()
41+
if projects:
42+
print("{} projects".format(pagination.total_available))
43+
project = projects[0]
44+
print(project.name)
45+
46+
print("Done")
47+
48+
49+
if __name__ == "__main__":
50+
main()

0 commit comments

Comments
 (0)