Skip to content

Commit 1d98fda

Browse files
authored
Merge pull request #1519 from tableau/development
Development to master in prep of release 0.34
2 parents 196d73a + c3ea910 commit 1d98fda

File tree

149 files changed

+3347
-1407
lines changed

Some content is hidden

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

149 files changed

+3347
-1407
lines changed

.github/workflows/meta-checks.yml

+14
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,20 @@ jobs:
1313
runs-on: ${{ matrix.os }}
1414

1515
steps:
16+
- name: Get pip cache dir
17+
id: pip-cache
18+
shell: bash
19+
run: |
20+
echo "dir=$(pip cache dir)" >> $GITHUB_OUTPUT
21+
22+
- name: cache
23+
uses: actions/cache@v4
24+
with:
25+
path: ${{ steps.pip-cache.outputs.dir }}
26+
key: ${{ runner.os }}-${{ matrix.python-version }}-pip-${{ hashFiles('pyproject.toml') }}
27+
restore-keys: |
28+
${{ runner.os }}-${{ matrix.python-version }}-pip-
29+
1630
- uses: actions/checkout@v4
1731

1832
- name: Set up Python ${{ matrix.python-version }} on ${{ matrix.os }}

.github/workflows/run-tests.yml

+15-1
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,25 @@ jobs:
1313
fail-fast: false
1414
matrix:
1515
os: [ubuntu-latest, macos-latest, windows-latest]
16-
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12']
16+
python-version: ['3.9', '3.10', '3.11', '3.12', '3.13']
1717

1818
runs-on: ${{ matrix.os }}
1919

2020
steps:
21+
- name: Get pip cache dir
22+
id: pip-cache
23+
shell: bash
24+
run: |
25+
echo "dir=$(pip cache dir)" >> $GITHUB_OUTPUT
26+
27+
- name: cache
28+
uses: actions/cache@v4
29+
with:
30+
path: ${{ steps.pip-cache.outputs.dir }}
31+
key: ${{ runner.os }}-${{ matrix.python-version }}-pip-${{ hashFiles('pyproject.toml') }}
32+
restore-keys: |
33+
${{ runner.os }}-${{ matrix.python-version }}-pip-
34+
2135
- uses: actions/checkout@v4
2236

2337
- name: Set up Python ${{ matrix.python-version }} on ${{ matrix.os }}

pyproject.toml

+9-9
Original file line numberDiff line numberDiff line change
@@ -14,42 +14,42 @@ readme = "README.md"
1414
dependencies = [
1515
'defusedxml>=0.7.1', # latest as at 7/31/23
1616
'packaging>=23.1', # latest as at 7/31/23
17-
'requests>=2.31', # latest as at 7/31/23
18-
'urllib3==2.2.2', # dependabot
17+
'requests>=2.32', # latest as at 7/31/23
18+
'urllib3>=2.2.2,<3',
1919
'typing_extensions>=4.0.1',
2020
]
21-
requires-python = ">=3.7"
21+
requires-python = ">=3.9"
2222
classifiers = [
2323
"Programming Language :: Python",
2424
"Programming Language :: Python :: 3",
25-
"Programming Language :: Python :: 3.8",
2625
"Programming Language :: Python :: 3.9",
2726
"Programming Language :: Python :: 3.10",
2827
"Programming Language :: Python :: 3.11",
29-
"Programming Language :: Python :: 3.12"
28+
"Programming Language :: Python :: 3.12",
29+
"Programming Language :: Python :: 3.13"
3030
]
3131
[project.urls]
3232
repository = "https://github.com/tableau/server-client-python"
3333

3434
[project.optional-dependencies]
35-
test = ["black==23.7", "build", "mypy==1.4", "pytest>=7.0", "pytest-cov", "pytest-subtests",
35+
test = ["black==24.8", "build", "mypy==1.4", "pytest>=7.0", "pytest-cov", "pytest-subtests",
3636
"requests-mock>=1.0,<2.0"]
3737

3838
[tool.black]
3939
line-length = 120
40-
target-version = ['py37', 'py38', 'py39', 'py310', 'py311', 'py312']
40+
target-version = ['py39', 'py310', 'py311', 'py312', 'py313']
4141

4242
[tool.mypy]
4343
check_untyped_defs = false
4444
disable_error_code = [
4545
'misc',
46-
# tableauserverclient\server\endpoint\datasources_endpoint.py:48: error: Cannot assign multiple types to name "FilePath" without an explicit "Type[...]" annotation [misc]
4746
'annotation-unchecked' # can be removed when check_untyped_defs = true
4847
]
49-
files = ["tableauserverclient", "test"]
48+
files = ["tableauserverclient", "test", "samples"]
5049
show_error_codes = true
5150
ignore_missing_imports = true # defusedxml library has no types
5251
no_implicit_reexport = true
52+
implicit_optional = true
5353

5454
[tool.pytest.ini_options]
5555
testpaths = ["test"]

samples/add_default_permission.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,10 @@ def main():
6363
for permission in new_default_permissions:
6464
grantee = permission.grantee
6565
capabilities = permission.capabilities
66-
print("\nCapabilities for {0} {1}:".format(grantee.tag_name, grantee.id))
66+
print(f"\nCapabilities for {grantee.tag_name} {grantee.id}:")
6767

6868
for capability in capabilities:
69-
print("\t{0} - {1}".format(capability, capabilities[capability]))
69+
print(f"\t{capability} - {capabilities[capability]}")
7070

7171
# Uncomment lines below to DELETE the new capability and the new project
7272
# rules_to_delete = TSC.PermissionsRule(

samples/create_group.py

+6-7
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
import os
1212

1313
from datetime import time
14-
from typing import List
1514

1615
import tableauserverclient as TSC
1716
from tableauserverclient import ServerResponseError
@@ -63,23 +62,23 @@ def main():
6362

6463
if args.file:
6564
filepath = os.path.abspath(args.file)
66-
print("Add users to site from file {}:".format(filepath))
67-
added: List[TSC.UserItem]
68-
failed: List[TSC.UserItem, TSC.ServerResponseError]
65+
print(f"Add users to site from file {filepath}:")
66+
added: list[TSC.UserItem]
67+
failed: list[TSC.UserItem, TSC.ServerResponseError]
6968
added, failed = server.users.create_from_file(filepath)
7069
for user, error in failed:
7170
print(user, error.code)
7271
if error.code == "409017":
7372
user = server.users.filter(name=user.name)[0]
7473
added.append(user)
75-
print("Adding users to group:{}".format(added))
74+
print(f"Adding users to group:{added}")
7675
for user in added:
77-
print("Adding user {}".format(user))
76+
print(f"Adding user {user}")
7877
try:
7978
server.groups.add_user(group, user.id)
8079
except ServerResponseError as serverError:
8180
if serverError.code == "409011":
82-
print("user {} is already a member of group {}".format(user.name, group.name))
81+
print(f"user {user.name} is already a member of group {group.name}")
8382
else:
8483
raise rError
8584

samples/create_project.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ def main():
8484
server.projects.populate_datasource_default_permissions(changed_project),
8585
server.projects.populate_permissions(changed_project)
8686
# Projects have default permissions set for the object types they contain
87-
print("Permissions from project {}:".format(changed_project.id))
87+
print(f"Permissions from project {changed_project.id}:")
8888
print(changed_project.permissions)
8989
print(
9090
changed_project.default_workbook_permissions,

samples/create_schedules.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ def main():
5555
)
5656
try:
5757
hourly_schedule = server.schedules.create(hourly_schedule)
58-
print("Hourly schedule created (ID: {}).".format(hourly_schedule.id))
58+
print(f"Hourly schedule created (ID: {hourly_schedule.id}).")
5959
except Exception as e:
6060
print(e)
6161

@@ -71,7 +71,7 @@ def main():
7171
)
7272
try:
7373
daily_schedule = server.schedules.create(daily_schedule)
74-
print("Daily schedule created (ID: {}).".format(daily_schedule.id))
74+
print(f"Daily schedule created (ID: {daily_schedule.id}).")
7575
except Exception as e:
7676
print(e)
7777

@@ -89,7 +89,7 @@ def main():
8989
)
9090
try:
9191
weekly_schedule = server.schedules.create(weekly_schedule)
92-
print("Weekly schedule created (ID: {}).".format(weekly_schedule.id))
92+
print(f"Weekly schedule created (ID: {weekly_schedule.id}).")
9393
except Exception as e:
9494
print(e)
9595
options = TSC.RequestOptions()
@@ -112,7 +112,7 @@ def main():
112112
)
113113
try:
114114
monthly_schedule = server.schedules.create(monthly_schedule)
115-
print("Monthly schedule created (ID: {}).".format(monthly_schedule.id))
115+
print(f"Monthly schedule created (ID: {monthly_schedule.id}).")
116116
except Exception as e:
117117
print(e)
118118

samples/explore_datasource.py

+11-11
Original file line numberDiff line numberDiff line change
@@ -51,16 +51,17 @@ def main():
5151
if args.publish:
5252
if default_project is not None:
5353
new_datasource = TSC.DatasourceItem(default_project.id)
54+
new_datasource.description = "Published with a description"
5455
new_datasource = server.datasources.publish(
5556
new_datasource, args.publish, TSC.Server.PublishMode.Overwrite
5657
)
57-
print("Datasource published. ID: {}".format(new_datasource.id))
58+
print(f"Datasource published. ID: {new_datasource.id}")
5859
else:
5960
print("Publish failed. Could not find the default project.")
6061

6162
# Gets all datasource items
6263
all_datasources, pagination_item = server.datasources.get()
63-
print("\nThere are {} datasources on site: ".format(pagination_item.total_available))
64+
print(f"\nThere are {pagination_item.total_available} datasources on site: ")
6465
print([datasource.name for datasource in all_datasources])
6566

6667
if all_datasources:
@@ -69,20 +70,19 @@ def main():
6970

7071
# Populate connections
7172
server.datasources.populate_connections(sample_datasource)
72-
print("\nConnections for {}: ".format(sample_datasource.name))
73-
print(
74-
[
75-
"{0}({1})".format(connection.id, connection.datasource_name)
76-
for connection in sample_datasource.connections
77-
]
78-
)
73+
print(f"\nConnections for {sample_datasource.name}: ")
74+
print([f"{connection.id}({connection.datasource_name})" for connection in sample_datasource.connections])
75+
76+
# Demonstrate that description is editable
77+
sample_datasource.description = "Description updated by TSC"
78+
server.datasources.update(sample_datasource)
7979

8080
# Add some tags to the datasource
8181
original_tag_set = set(sample_datasource.tags)
8282
sample_datasource.tags.update("a", "b", "c", "d")
8383
server.datasources.update(sample_datasource)
84-
print("\nOld tag set: {}".format(original_tag_set))
85-
print("New tag set: {}".format(sample_datasource.tags))
84+
print(f"\nOld tag set: {original_tag_set}")
85+
print(f"New tag set: {sample_datasource.tags}")
8686

8787
# Delete all tags that were added by setting tags to original
8888
sample_datasource.tags = original_tag_set

samples/explore_favorites.py

+7-9
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import argparse
44
import logging
55
import tableauserverclient as TSC
6-
from tableauserverclient import Resource
6+
from tableauserverclient.models import Resource
77

88

99
def main():
@@ -39,15 +39,15 @@ def main():
3939
# get all favorites on site for the logged on user
4040
user: TSC.UserItem = TSC.UserItem()
4141
user.id = server.user_id
42-
print("Favorites for user: {}".format(user.id))
42+
print(f"Favorites for user: {user.id}")
4343
server.favorites.get(user)
4444
print(user.favorites)
4545

4646
# get list of workbooks
4747
all_workbook_items, pagination_item = server.workbooks.get()
4848
if all_workbook_items is not None and len(all_workbook_items) > 0:
49-
my_workbook: TSC.WorkbookItem = all_workbook_items[0]
50-
server.favorites.add_favorite(server, user, Resource.Workbook.name(), all_workbook_items[0])
49+
my_workbook = all_workbook_items[0]
50+
server.favorites.add_favorite(user, Resource.Workbook, all_workbook_items[0])
5151
print(
5252
"Workbook added to favorites. Workbook Name: {}, Workbook ID: {}".format(
5353
my_workbook.name, my_workbook.id
@@ -57,7 +57,7 @@ def main():
5757
if views is not None and len(views) > 0:
5858
my_view = views[0]
5959
server.favorites.add_favorite_view(user, my_view)
60-
print("View added to favorites. View Name: {}, View ID: {}".format(my_view.name, my_view.id))
60+
print(f"View added to favorites. View Name: {my_view.name}, View ID: {my_view.id}")
6161

6262
all_datasource_items, pagination_item = server.datasources.get()
6363
if all_datasource_items:
@@ -70,12 +70,10 @@ def main():
7070
)
7171

7272
server.favorites.delete_favorite_workbook(user, my_workbook)
73-
print(
74-
"Workbook deleted from favorites. Workbook Name: {}, Workbook ID: {}".format(my_workbook.name, my_workbook.id)
75-
)
73+
print(f"Workbook deleted from favorites. Workbook Name: {my_workbook.name}, Workbook ID: {my_workbook.id}")
7674

7775
server.favorites.delete_favorite_view(user, my_view)
78-
print("View deleted from favorites. View Name: {}, View ID: {}".format(my_view.name, my_view.id))
76+
print(f"View deleted from favorites. View Name: {my_view.name}, View ID: {my_view.id}")
7977

8078
server.favorites.delete_favorite_datasource(user, my_datasource)
8179
print(

samples/explore_site.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ def main():
4949

5050
if args.delete:
5151
print("You can only delete the site you are currently in")
52-
print("Delete site `{}`?".format(current_site.name))
52+
print(f"Delete site `{current_site.name}`?")
5353
# server.sites.delete(server.site_id)
5454

5555
elif args.create:

samples/explore_webhooks.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,11 @@ def main():
5252
new_webhook.event = "datasource-created"
5353
print(new_webhook)
5454
new_webhook = server.webhooks.create(new_webhook)
55-
print("Webhook created. ID: {}".format(new_webhook.id))
55+
print(f"Webhook created. ID: {new_webhook.id}")
5656

5757
# Gets all webhook items
5858
all_webhooks, pagination_item = server.webhooks.get()
59-
print("\nThere are {} webhooks on site: ".format(pagination_item.total_available))
59+
print(f"\nThere are {pagination_item.total_available} webhooks on site: ")
6060
print([webhook.name for webhook in all_webhooks])
6161

6262
if all_webhooks:

0 commit comments

Comments
 (0)