Skip to content

Commit fd3cc99

Browse files
vchavatapallijacalata
authored andcommitted
Updated TSC with new API's
1 parent 6498a4f commit fd3cc99

File tree

9 files changed

+231
-161
lines changed

9 files changed

+231
-161
lines changed

samples/update_connection_auth.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,15 @@
44

55

66
def main():
7-
parser = argparse.ArgumentParser(
8-
description="Update a single connection on a datasource or workbook to embed credentials"
9-
)
7+
parser = argparse.ArgumentParser(description="Update a single connection on a datasource or workbook to embed credentials")
108

119
# Common options
1210
parser.add_argument("--server", "-s", help="Server address", required=True)
1311
parser.add_argument("--site", "-S", help="Site name", required=True)
1412
parser.add_argument("--token-name", "-p", help="Personal access token name", required=True)
1513
parser.add_argument("--token-value", "-v", help="Personal access token value", required=True)
1614
parser.add_argument(
17-
"--logging-level",
18-
"-l",
15+
"--logging-level", "-l",
1916
choices=["debug", "info", "error"],
2017
default="error",
2118
help="Logging level (default: error)",
@@ -39,7 +36,10 @@ def main():
3936
server = TSC.Server(args.server, use_server_version=True)
4037

4138
with server.auth.sign_in(tableau_auth):
42-
endpoint = {"workbook": server.workbooks, "datasource": server.datasources}.get(args.resource_type)
39+
endpoint = {
40+
"workbook": server.workbooks,
41+
"datasource": server.datasources
42+
}.get(args.resource_type)
4343

4444
update_function = endpoint.update_connection
4545
resource = endpoint.get_by_id(args.resource_id)
@@ -51,7 +51,7 @@ def main():
5151
connection = connections[0]
5252
connection.username = args.datasource_username
5353
connection.password = args.datasource_password
54-
connection.auth_type = args.authentication_type
54+
connection.authentication_type = args.authentication_type
5555
connection.embed_password = True
5656

5757
updated_connection = update_function(resource, connection)

samples/update_connections_auth.py

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ def main():
99
# Common options
1010
parser.add_argument("--server", "-s", help="Server address", required=True)
1111
parser.add_argument("--site", "-S", help="Site name", required=True)
12-
parser.add_argument("--token-name", "-p", help="Personal access token name", required=True)
13-
parser.add_argument("--token-value", "-v", help="Personal access token value", required=True)
12+
parser.add_argument("--username", "-p", help="Personal access token name", required=True)
13+
parser.add_argument("--password", "-v", help="Personal access token value", required=True)
1414
parser.add_argument(
1515
"--logging-level",
1616
"-l",
@@ -25,21 +25,22 @@ def main():
2525
parser.add_argument("datasource_username")
2626
parser.add_argument("authentication_type")
2727
parser.add_argument("--datasource_password", default=None, help="Datasource password (optional)")
28-
parser.add_argument(
29-
"--embed_password", default="true", choices=["true", "false"], help="Embed password (default: true)"
30-
)
28+
parser.add_argument("--embed_password", default="true", choices=["true", "false"], help="Embed password (default: true)")
3129

3230
args = parser.parse_args()
3331

3432
# Set logging level
3533
logging_level = getattr(logging, args.logging_level.upper())
3634
logging.basicConfig(level=logging_level)
3735

38-
tableau_auth = TSC.PersonalAccessTokenAuth(args.token_name, args.token_value, site_id=args.site)
36+
tableau_auth = TSC.TableauAuth(args.username, args.password, site_id=args.site)
3937
server = TSC.Server(args.server, use_server_version=True)
4038

4139
with server.auth.sign_in(tableau_auth):
42-
endpoint = {"workbook": server.workbooks, "datasource": server.datasources}.get(args.resource_type)
40+
endpoint = {
41+
"workbook": server.workbooks,
42+
"datasource": server.datasources
43+
}.get(args.resource_type)
4344

4445
resource = endpoint.get_by_id(args.resource_id)
4546
endpoint.populate_connections(resource)
@@ -48,16 +49,16 @@ def main():
4849
embed_password = args.embed_password.lower() == "true"
4950

5051
# Call unified update_connections method
51-
connection_items = endpoint.update_connections(
52+
updated_ids = endpoint.update_connections(
5253
resource,
5354
connection_luids=connection_luids,
5455
authentication_type=args.authentication_type,
5556
username=args.datasource_username,
5657
password=args.datasource_password,
57-
embed_password=embed_password,
58+
embed_password=embed_password
5859
)
5960

60-
print(f"Updated connections on {args.resource_type} {args.resource_id}: {connection_items}")
61+
print(f"Updated connections on {args.resource_type} {args.resource_id}: {updated_ids}")
6162

6263

6364
if __name__ == "__main__":

tableauserverclient/models/connection_item.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,10 @@ def connection_type(self) -> Optional[str]:
8484
def query_tagging(self) -> Optional[bool]:
8585
return self._query_tagging
8686

87+
@property
88+
def auth_type(self) -> Optional[str]:
89+
return self._auth_type
90+
8791
@query_tagging.setter
8892
@property_is_boolean
8993
def query_tagging(self, value: Optional[bool]):

tableauserverclient/server/endpoint/datasources_endpoint.py

Lines changed: 33 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -376,14 +376,8 @@ def update_connection(
376376

377377
@api(version="3.26")
378378
def update_connections(
379-
self,
380-
datasource_item: DatasourceItem,
381-
connection_luids: Iterable[str],
382-
authentication_type: str,
383-
username: Optional[str] = None,
384-
password: Optional[str] = None,
385-
embed_password: Optional[bool] = None,
386-
) -> list[ConnectionItem]:
379+
self, datasource_item: DatasourceItem, connection_luids: list[str], authentication_type: str, username: Optional[str] = None, password: Optional[str] = None, embed_password: Optional[bool] = None
380+
) -> list[str]:
387381
"""
388382
Bulk updates one or more datasource connections by LUID.
389383
@@ -392,7 +386,7 @@ def update_connections(
392386
datasource_item : DatasourceItem
393387
The datasource item containing the connections.
394388
395-
connection_luids : Iterable of str
389+
connection_luids : list of str
396390
The connection LUIDs to update.
397391
398392
authentication_type : str
@@ -409,25 +403,42 @@ def update_connections(
409403
410404
Returns
411405
-------
412-
Iterable of str
406+
list of str
413407
The connection LUIDs that were updated.
414408
"""
409+
from xml.etree.ElementTree import Element, SubElement, tostring
415410

416411
url = f"{self.baseurl}/{datasource_item.id}/connections"
412+
print("Method URL:", url)
417413

418-
request_body = RequestFactory.Datasource.update_connections_req(
419-
connection_luids=connection_luids,
420-
authentication_type=authentication_type,
421-
username=username,
422-
password=password,
423-
embed_password=embed_password,
424-
)
425-
server_response = self.put_request(url, request_body)
426-
connection_items = ConnectionItem.from_response(server_response.content, self.parent_srv.namespace)
427-
updated_ids: list[str] = [conn.id for conn in connection_items]
414+
ts_request = Element("tsRequest")
415+
416+
# <connectionLuids>
417+
conn_luids_elem = SubElement(ts_request, "connectionLuids")
418+
for luid in connection_luids:
419+
SubElement(conn_luids_elem, "connectionLuid").text = luid
420+
421+
# <connection>
422+
connection_elem = SubElement(ts_request, "connection")
423+
connection_elem.set("authenticationType", authentication_type)
428424

429-
logger.info(f"Updated connections for datasource {datasource_item.id}: {', '.join(updated_ids)}")
430-
return connection_items
425+
if username:
426+
connection_elem.set("userName", username)
427+
428+
if password:
429+
connection_elem.set("password", password)
430+
431+
if embed_password is not None:
432+
connection_elem.set("embedPassword", str(embed_password).lower())
433+
434+
request_body = tostring(ts_request)
435+
436+
response = self.put_request(url, request_body)
437+
438+
logger.info(
439+
f"Updated connections for datasource {datasource_item.id}: {', '.join(connection_luids)}"
440+
)
441+
return connection_luids
431442

432443
@api(version="2.8")
433444
def refresh(self, datasource_item: Union[DatasourceItem, str], incremental: bool = False) -> JobItem:

tableauserverclient/server/endpoint/workbooks_endpoint.py

Lines changed: 49 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -330,79 +330,69 @@ def update_connection(self, workbook_item: WorkbookItem, connection_item: Connec
330330

331331
# Update workbook_connections
332332
@api(version="3.26")
333-
def update_connections(
334-
self,
335-
workbook_item: WorkbookItem,
336-
connection_luids: Iterable[str],
337-
authentication_type: str,
338-
username: Optional[str] = None,
339-
password: Optional[str] = None,
340-
embed_password: Optional[bool] = None,
341-
) -> list[ConnectionItem]:
342-
"""
343-
Bulk updates one or more workbook connections by LUID, including authenticationType, username, password, and embedPassword.
333+
def update_connections(self, workbook_item: WorkbookItem, connection_luids: list[str], authentication_type: str, username: Optional[str] = None, password: Optional[str] = None, embed_password: Optional[bool] = None
334+
) -> list[str]:
335+
"""
336+
Bulk updates one or more workbook connections by LUID, including authenticationType, username, password, and embedPassword.
344337
345-
Parameters
346-
----------
347-
workbook_item : WorkbookItem
348-
The workbook item containing the connections.
338+
Parameters
339+
----------
340+
workbook_item : WorkbookItem
341+
The workbook item containing the connections.
349342
350-
connection_luids : Iterable of str
351-
The connection LUIDs to update.
343+
connection_luids : list of str
344+
The connection LUIDs to update.
352345
353-
authentication_type : str
354-
The authentication type to use (e.g., 'AD Service Principal').
346+
authentication_type : str
347+
The authentication type to use (e.g., 'AD Service Principal').
355348
356-
username : str, optional
357-
The username to set (e.g., client ID for keypair auth).
349+
username : str, optional
350+
The username to set (e.g., client ID for keypair auth).
358351
359-
password : str, optional
360-
The password or secret to set.
352+
password : str, optional
353+
The password or secret to set.
361354
362-
embed_password : bool, optional
363-
Whether to embed the password.
355+
embed_password : bool, optional
356+
Whether to embed the password.
364357
365-
Returns
366-
-------
367-
Iterable of str
368-
The connection LUIDs that were updated.
369-
"""
358+
Returns
359+
-------
360+
list of str
361+
The connection LUIDs that were updated.
362+
"""
363+
from xml.etree.ElementTree import Element, SubElement, tostring
370364

371-
url = f"{self.baseurl}/{workbook_item.id}/connections"
365+
url = f"{self.baseurl}/{workbook_item.id}/connections"
372366

373-
request_body = RequestFactory.Workbook.update_connections_req(
374-
connection_luids,
375-
authentication_type,
376-
username=username,
377-
password=password,
378-
embed_password=embed_password,
379-
)
367+
ts_request = Element("tsRequest")
380368

381-
# Send request
382-
server_response = self.put_request(url, request_body)
383-
connection_items = ConnectionItem.from_response(server_response.content, self.parent_srv.namespace)
384-
updated_ids: list[str] = [conn.id for conn in connection_items]
369+
# <connectionLuids>
370+
conn_luids_elem = SubElement(ts_request, "connectionLuids")
371+
for luid in connection_luids:
372+
SubElement(conn_luids_elem, "connectionLuid").text = luid
385373

386-
logger.info(f"Updated connections for workbook {workbook_item.id}: {', '.join(updated_ids)}")
387-
return connection_items
374+
# <connection>
375+
connection_elem = SubElement(ts_request, "connection")
376+
connection_elem.set("authenticationType", authentication_type)
388377

389-
T = TypeVar("T", bound=FileObjectW)
378+
if username:
379+
connection_elem.set("userName", username)
390380

391-
@overload
392-
def download(
393-
self,
394-
workbook_id: str,
395-
filepath: T,
396-
include_extract: bool = True,
397-
) -> T: ...
381+
if password:
382+
connection_elem.set("password", password)
398383

399-
@overload
400-
def download(
401-
self,
402-
workbook_id: str,
403-
filepath: Optional[FilePath] = None,
404-
include_extract: bool = True,
405-
) -> str: ...
384+
if embed_password is not None:
385+
connection_elem.set("embedPassword", str(embed_password).lower())
386+
387+
request_body = tostring(ts_request)
388+
389+
# Send request
390+
response = self.put_request(url, request_body)
391+
392+
logger.info(
393+
f"Updated connections for workbook {workbook_item.id}: {', '.join(connection_luids)}"
394+
)
395+
return connection_luids
406396

407397
# Download workbook contents with option of passing in filepath
408398
@api(version="2.0")
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<tsResponse xmlns="http://tableau.com/api"
33
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4-
xsi:schemaLocation="http://tableau.com/api https://help.tableau.com/samples/en-us/rest_api/ts-api_3_25.xsd">
4+
xsi:schemaLocation="http://tableau.com/api http://tableau.com/api/ts-api-3.26.xsd">
55
<connections>
66
<connection id="be786ae0-d2bf-4a4b-9b34-e2de8d2d4488"
77
type="sqlserver"
88
serverAddress="updated-server"
99
serverPort="1433"
1010
userName="user1"
1111
embedPassword="true"
12-
authenticationType="auth-keypair" />
12+
authentication="auth-keypair" />
1313
<connection id="a1b2c3d4-e5f6-7a8b-9c0d-123456789abc"
1414
type="sqlserver"
1515
serverAddress="updated-server"
1616
serverPort="1433"
1717
userName="user1"
1818
embedPassword="true"
19-
authenticationType="auth-keypair" />
19+
authentication="auth-keypair" />
2020
</connections>
2121
</tsResponse>
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<tsResponse xmlns="http://tableau.com/api"
33
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4-
xsi:schemaLocation="http://tableau.com/api https://help.tableau.com/samples/en-us/rest_api/ts-api_3_25.xsd">
4+
xsi:schemaLocation="http://tableau.com/api http://tableau.com/api/ts-api-3.26.xsd">
55
<connections>
66
<connection id="abc12345-def6-7890-gh12-ijklmnopqrst"
77
type="sqlserver"
88
serverAddress="updated-db-host"
99
serverPort="1433"
1010
userName="svc-client"
1111
embedPassword="true"
12-
authenticationType="AD Service Principal" />
12+
authentication="AD Service Principal" />
1313
<connection id="1234abcd-5678-efgh-ijkl-0987654321mn"
1414
type="sqlserver"
1515
serverAddress="updated-db-host"
1616
serverPort="1433"
1717
userName="svc-client"
1818
embedPassword="true"
19-
authenticationType="AD Service Principal" />
19+
authentication="AD Service Principal" />
2020
</connections>
2121
</tsResponse>

0 commit comments

Comments
 (0)