Skip to content

Commit 72885d1

Browse files
jorwoodsjacalata
authored andcommitted
chore: refactor XML payload into RequestFactory
Also correct the type hints to clarify that it accepts any Iterable.
1 parent fd3cc99 commit 72885d1

File tree

5 files changed

+82
-113
lines changed

5 files changed

+82
-113
lines changed

tableauserverclient/models/connection_item.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,6 @@ 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-
9187
@query_tagging.setter
9288
@property_is_boolean
9389
def query_tagging(self, value: Optional[bool]):

tableauserverclient/server/endpoint/datasources_endpoint.py

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

377377
@api(version="3.26")
378378
def update_connections(
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]:
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+
) -> Iterable[str]:
381387
"""
382388
Bulk updates one or more datasource connections by LUID.
383389
@@ -386,7 +392,7 @@ def update_connections(
386392
datasource_item : DatasourceItem
387393
The datasource item containing the connections.
388394
389-
connection_luids : list of str
395+
connection_luids : Iterable of str
390396
The connection LUIDs to update.
391397
392398
authentication_type : str
@@ -403,41 +409,23 @@ def update_connections(
403409
404410
Returns
405411
-------
406-
list of str
412+
Iterable of str
407413
The connection LUIDs that were updated.
408414
"""
409-
from xml.etree.ElementTree import Element, SubElement, tostring
410415

411416
url = f"{self.baseurl}/{datasource_item.id}/connections"
412417
print("Method URL:", url)
413418

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)
424-
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-
419+
request_body = RequestFactory.Datasource.update_connections_req(
420+
connection_luids=connection_luids,
421+
authentication_type=authentication_type,
422+
username=username,
423+
password=password,
424+
embed_password=embed_password,
425+
)
436426
response = self.put_request(url, request_body)
437427

438-
logger.info(
439-
f"Updated connections for datasource {datasource_item.id}: {', '.join(connection_luids)}"
440-
)
428+
logger.info(f"Updated connections for datasource {datasource_item.id}: {', '.join(connection_luids)}")
441429
return connection_luids
442430

443431
@api(version="2.8")

tableauserverclient/server/endpoint/workbooks_endpoint.py

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

331331
# Update workbook_connections
332332
@api(version="3.26")
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.
337-
338-
Parameters
339-
----------
340-
workbook_item : WorkbookItem
341-
The workbook item containing the connections.
342-
343-
connection_luids : list of str
344-
The connection LUIDs to update.
345-
346-
authentication_type : str
347-
The authentication type to use (e.g., 'AD Service Principal').
348-
349-
username : str, optional
350-
The username to set (e.g., client ID for keypair auth).
351-
352-
password : str, optional
353-
The password or secret to set.
354-
355-
embed_password : bool, optional
356-
Whether to embed the password.
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+
) -> Iterable[str]:
342+
"""
343+
Bulk updates one or more workbook connections by LUID, including authenticationType, username, password, and embedPassword.
357344
358-
Returns
359-
-------
360-
list of str
361-
The connection LUIDs that were updated.
362-
"""
363-
from xml.etree.ElementTree import Element, SubElement, tostring
345+
Parameters
346+
----------
347+
workbook_item : WorkbookItem
348+
The workbook item containing the connections.
364349
365-
url = f"{self.baseurl}/{workbook_item.id}/connections"
350+
connection_luids : Iterable of str
351+
The connection LUIDs to update.
366352
367-
ts_request = Element("tsRequest")
353+
authentication_type : str
354+
The authentication type to use (e.g., 'AD Service Principal').
368355
369-
# <connectionLuids>
370-
conn_luids_elem = SubElement(ts_request, "connectionLuids")
371-
for luid in connection_luids:
372-
SubElement(conn_luids_elem, "connectionLuid").text = luid
356+
username : str, optional
357+
The username to set (e.g., client ID for keypair auth).
373358
374-
# <connection>
375-
connection_elem = SubElement(ts_request, "connection")
376-
connection_elem.set("authenticationType", authentication_type)
359+
password : str, optional
360+
The password or secret to set.
377361
378-
if username:
379-
connection_elem.set("userName", username)
362+
embed_password : bool, optional
363+
Whether to embed the password.
380364
381-
if password:
382-
connection_elem.set("password", password)
365+
Returns
366+
-------
367+
Iterable of str
368+
The connection LUIDs that were updated.
369+
"""
383370

384-
if embed_password is not None:
385-
connection_elem.set("embedPassword", str(embed_password).lower())
371+
url = f"{self.baseurl}/{workbook_item.id}/connections"
386372

387-
request_body = tostring(ts_request)
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+
)
388380

389-
# Send request
390-
response = self.put_request(url, request_body)
381+
# Send request
382+
response = self.put_request(url, request_body)
391383

392-
logger.info(
393-
f"Updated connections for workbook {workbook_item.id}: {', '.join(connection_luids)}"
394-
)
395-
return connection_luids
384+
logger.info(f"Updated connections for workbook {workbook_item.id}: {', '.join(connection_luids)}")
385+
return connection_luids
396386

397387
# Download workbook contents with option of passing in filepath
398388
@api(version="2.0")

test/test_datasource.py

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -158,29 +158,27 @@ def test_update_copy_fields(server) -> None:
158158

159159

160160
def test_update_connections(self) -> None:
161-
populate_xml, response_xml = read_xml_assets(
162-
POPULATE_CONNECTIONS_XML,
163-
UPDATE_CONNECTIONS_XML
164-
)
161+
populate_xml, response_xml = read_xml_assets(POPULATE_CONNECTIONS_XML, UPDATE_CONNECTIONS_XML)
165162

166163
with requests_mock.Mocker() as m:
167164

168165
datasource_id = "9dbd2263-16b5-46e1-9c43-a76bb8ab65fb"
169-
connection_luids = [
170-
"be786ae0-d2bf-4a4b-9b34-e2de8d2d4488",
171-
"a1b2c3d4-e5f6-7a8b-9c0d-123456789abc"
172-
]
166+
connection_luids = ["be786ae0-d2bf-4a4b-9b34-e2de8d2d4488", "a1b2c3d4-e5f6-7a8b-9c0d-123456789abc"]
173167

174168
datasource = TSC.DatasourceItem(datasource_id)
175169
datasource._id = "9dbd2263-16b5-46e1-9c43-a76bb8ab65fb"
176170
datasource.owner_id = "dd2239f6-ddf1-4107-981a-4cf94e415794"
177171
self.server.version = "3.26"
178172

179173
url = f"{self.server.baseurl}/{datasource.id}/connections"
180-
m.get("http://test/api/3.26/sites/dad65087-b08b-4603-af4e-2887b8aafc67/datasources/9dbd2263-16b5-46e1-9c43-a76bb8ab65fb/connections", text=populate_xml)
181-
m.put("http://test/api/3.26/sites/dad65087-b08b-4603-af4e-2887b8aafc67/datasources/9dbd2263-16b5-46e1-9c43-a76bb8ab65fb/connections", text=response_xml)
182-
183-
174+
m.get(
175+
"http://test/api/3.26/sites/dad65087-b08b-4603-af4e-2887b8aafc67/datasources/9dbd2263-16b5-46e1-9c43-a76bb8ab65fb/connections",
176+
text=populate_xml,
177+
)
178+
m.put(
179+
"http://test/api/3.26/sites/dad65087-b08b-4603-af4e-2887b8aafc67/datasources/9dbd2263-16b5-46e1-9c43-a76bb8ab65fb/connections",
180+
text=response_xml,
181+
)
184182

185183
print("BASEURL:", self.server.baseurl)
186184
print("Calling PUT on:", f"{self.server.baseurl}/{datasource.id}/connections")
@@ -191,12 +189,11 @@ def test_update_connections(self) -> None:
191189
authentication_type="auth-keypair",
192190
username="testuser",
193191
password="testpass",
194-
embed_password=True
192+
embed_password=True,
195193
)
196194

197195
self.assertEqual(updated_luids, connection_luids)
198196

199-
200197
def test_populate_permissions(self) -> None:
201198
with open(asset(POPULATE_PERMISSIONS_XML), "rb") as f:
202199
response_xml = f.read().decode("utf-8")

test/test_workbook.py

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -709,34 +709,32 @@ def test_publish_with_thumbnails_user_id(server: TSC.Server) -> None:
709709

710710

711711
def test_update_workbook_connections(self) -> None:
712-
populate_xml, response_xml = read_xml_assets(
713-
POPULATE_CONNECTIONS_XML,
714-
UPDATE_CONNECTIONS_XML
715-
)
716-
712+
populate_xml, response_xml = read_xml_assets(POPULATE_CONNECTIONS_XML, UPDATE_CONNECTIONS_XML)
717713

718714
with requests_mock.Mocker() as m:
719715
workbook_id = "1a2b3c4d-5e6f-7a8b-9c0d-112233445566"
720-
connection_luids = [
721-
"abc12345-def6-7890-gh12-ijklmnopqrst",
722-
"1234abcd-5678-efgh-ijkl-0987654321mn"
723-
]
716+
connection_luids = ["abc12345-def6-7890-gh12-ijklmnopqrst", "1234abcd-5678-efgh-ijkl-0987654321mn"]
724717

725718
workbook = TSC.WorkbookItem(workbook_id)
726719
workbook._id = workbook_id
727720
self.server.version = "3.26"
728721
url = f"{self.server.baseurl}/{workbook_id}/connections"
729-
m.get("http://test/api/3.26/sites/dad65087-b08b-4603-af4e-2887b8aafc67/workbooks/1a2b3c4d-5e6f-7a8b-9c0d-112233445566/connections", text=populate_xml)
730-
m.put("http://test/api/3.26/sites/dad65087-b08b-4603-af4e-2887b8aafc67/workbooks/1a2b3c4d-5e6f-7a8b-9c0d-112233445566/connections", text=response_xml)
731-
722+
m.get(
723+
"http://test/api/3.26/sites/dad65087-b08b-4603-af4e-2887b8aafc67/workbooks/1a2b3c4d-5e6f-7a8b-9c0d-112233445566/connections",
724+
text=populate_xml,
725+
)
726+
m.put(
727+
"http://test/api/3.26/sites/dad65087-b08b-4603-af4e-2887b8aafc67/workbooks/1a2b3c4d-5e6f-7a8b-9c0d-112233445566/connections",
728+
text=response_xml,
729+
)
732730

733731
updated_luids = self.server.workbooks.update_connections(
734732
workbook_item=workbook,
735733
connection_luids=connection_luids,
736734
authentication_type="AD Service Principal",
737735
username="svc-client",
738736
password="secret-token",
739-
embed_password=True
737+
embed_password=True,
740738
)
741739

742740
self.assertEqual(updated_luids, connection_luids)

0 commit comments

Comments
 (0)