Skip to content

Commit d84fbc2

Browse files
authored
Merge branch 'development' into jorwoods/combining_permissionsrules
2 parents cad1711 + 48debe6 commit d84fbc2

File tree

7 files changed

+61
-6
lines changed

7 files changed

+61
-6
lines changed

pyproject.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ classifiers = [
3232
repository = "https://github.com/tableau/server-client-python"
3333

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

3838
[tool.black]

tableauserverclient/models/datasource_item.py

+12
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ def __init__(self, project_id: Optional[str] = None, name: Optional[str] = None)
4747
self._initial_tags: Set = set()
4848
self._project_name: Optional[str] = None
4949
self._revisions = None
50+
self._size: Optional[int] = None
5051
self._updated_at = None
5152
self._use_remote_query_agent = None
5253
self._webpage_url = None
@@ -182,6 +183,10 @@ def revisions(self) -> List[RevisionItem]:
182183
raise UnpopulatedPropertyError(error)
183184
return self._revisions()
184185

186+
@property
187+
def size(self) -> Optional[int]:
188+
return self._size
189+
185190
def _set_connections(self, connections):
186191
self._connections = connections
187192

@@ -217,6 +222,7 @@ def _parse_common_elements(self, datasource_xml, ns):
217222
updated_at,
218223
use_remote_query_agent,
219224
webpage_url,
225+
size,
220226
) = self._parse_element(datasource_xml, ns)
221227
self._set_values(
222228
ask_data_enablement,
@@ -237,6 +243,7 @@ def _parse_common_elements(self, datasource_xml, ns):
237243
updated_at,
238244
use_remote_query_agent,
239245
webpage_url,
246+
size,
240247
)
241248
return self
242249

@@ -260,6 +267,7 @@ def _set_values(
260267
updated_at,
261268
use_remote_query_agent,
262269
webpage_url,
270+
size,
263271
):
264272
if ask_data_enablement is not None:
265273
self._ask_data_enablement = ask_data_enablement
@@ -297,6 +305,8 @@ def _set_values(
297305
self._use_remote_query_agent = str(use_remote_query_agent).lower() == "true"
298306
if webpage_url:
299307
self._webpage_url = webpage_url
308+
if size is not None:
309+
self._size = int(size)
300310

301311
@classmethod
302312
def from_response(cls, resp: str, ns: Dict) -> List["DatasourceItem"]:
@@ -330,6 +340,7 @@ def _parse_element(datasource_xml: ET.Element, ns: Dict) -> Tuple:
330340
has_extracts = datasource_xml.get("hasExtracts", None)
331341
use_remote_query_agent = datasource_xml.get("useRemoteQueryAgent", None)
332342
webpage_url = datasource_xml.get("webpageUrl", None)
343+
size = datasource_xml.get("size", None)
333344

334345
tags = None
335346
tags_elem = datasource_xml.find(".//t:tags", namespaces=ns)
@@ -372,4 +383,5 @@ def _parse_element(datasource_xml: ET.Element, ns: Dict) -> Tuple:
372383
updated_at,
373384
use_remote_query_agent,
374385
webpage_url,
386+
size,
375387
)

tableauserverclient/server/request_factory.py

+7-2
Original file line numberDiff line numberDiff line change
@@ -1061,8 +1061,13 @@ class Connection(object):
10611061
@_tsrequest_wrapped
10621062
def update_req(self, xml_request: ET.Element, connection_item: "ConnectionItem") -> None:
10631063
connection_element = ET.SubElement(xml_request, "connection")
1064-
if connection_item.server_address is not None:
1065-
connection_element.attrib["serverAddress"] = connection_item.server_address.lower()
1064+
if (server_address := connection_item.server_address) is not None:
1065+
if (conn_type := connection_item.connection_type) is not None:
1066+
if conn_type.casefold() != "odata".casefold():
1067+
server_address = server_address.lower()
1068+
else:
1069+
server_address = server_address.lower()
1070+
connection_element.attrib["serverAddress"] = server_address
10661071
if connection_item.server_port is not None:
10671072
connection_element.attrib["serverPort"] = str(connection_item.server_port)
10681073
if connection_item.username is not None:

test/assets/datasource_get.xml

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22
<tsResponse xmlns="http://tableau.com/api" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://tableau.com/api http://tableau.com/api/ts-api-2.3.xsd">
33
<pagination pageNumber="1" pageSize="100" totalAvailable="2" />
44
<datasources>
5-
<datasource id="e76a1461-3b1d-4588-bf1b-17551a879ad9" name="SampleDS" contentUrl="SampleDS" description="SampleDsDescription" type="dataengine" createdAt="2016-08-11T21:22:40Z" updatedAt="2016-08-11T21:34:17Z" encryptExtracts="false" hasExtracts="true" useRemoteQueryAgent="false" webpageUrl="https://web.com">
5+
<datasource id="e76a1461-3b1d-4588-bf1b-17551a879ad9" name="SampleDS" size="4096" contentUrl="SampleDS" description="SampleDsDescription" type="dataengine" createdAt="2016-08-11T21:22:40Z" updatedAt="2016-08-11T21:34:17Z" encryptExtracts="false" hasExtracts="true" useRemoteQueryAgent="false" webpageUrl="https://web.com">
66
<project id="ee8c6e70-43b6-11e6-af4f-f7b0d8e20760" name="default" />
77
<owner id="5de011f8-5aa9-4d5b-b991-f462c8dd6bb7" />
88
<tags />
99
</datasource>
10-
<datasource id="9dbd2263-16b5-46e1-9c43-a76bb8ab65fb" name="Sample datasource" description="description Sample" contentUrl="Sampledatasource" type="dataengine" createdAt="2016-08-04T21:31:55Z" updatedAt="2016-08-04T21:31:55Z" encryptExtracts="true" hasExtracts="false" useRemoteQueryAgent="true" webpageUrl="https://page.com">
10+
<datasource id="9dbd2263-16b5-46e1-9c43-a76bb8ab65fb" name="Sample datasource" description="description Sample" size="10240" contentUrl="Sampledatasource" type="dataengine" createdAt="2016-08-04T21:31:55Z" updatedAt="2016-08-04T21:31:55Z" encryptExtracts="true" hasExtracts="false" useRemoteQueryAgent="true" webpageUrl="https://page.com">
1111
<project id="ee8c6e70-43b6-11e6-af4f-f7b0d8e20760" name="default" />
1212
<owner id="5de011f8-5aa9-4d5b-b991-f462c8dd6bb7" />
1313
<tags>
@@ -17,4 +17,4 @@
1717
</tags>
1818
</datasource>
1919
</datasources>
20-
</tsResponse>
20+
</tsResponse>

test/assets/odata_connection.xml

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?xml version='1.0' encoding='UTF-8'?><tsResponse xmlns="http://tableau.com/api" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://tableau.com/api https://help.tableau.com/samples/en-us/rest_api/ts-api_3_23.xsd">
2+
<connections>
3+
<connection id="17376070-64d1-4d17-acb4-a56e4b5b1768" type="odata" embedPassword="false" serverAddress="https://odata.website.com/TestODataEndpoint" userName="" queryTaggingEnabled="false">
4+
<datasource id="d82f784e-178f-4b7e-a723-d8f615155a42" name="People (services.odata.org/ODataPeopleService/People)"/>
5+
</connection>
6+
</connections>
7+
</tsResponse>

test/test_datasource.py

+2
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ def test_get(self) -> None:
5252
self.assertEqual("dataengine", all_datasources[0].datasource_type)
5353
self.assertEqual("SampleDsDescription", all_datasources[0].description)
5454
self.assertEqual("SampleDS", all_datasources[0].content_url)
55+
self.assertEqual(4096, all_datasources[0].size)
5556
self.assertEqual("2016-08-11T21:22:40Z", format_datetime(all_datasources[0].created_at))
5657
self.assertEqual("2016-08-11T21:34:17Z", format_datetime(all_datasources[0].updated_at))
5758
self.assertEqual("default", all_datasources[0].project_name)
@@ -67,6 +68,7 @@ def test_get(self) -> None:
6768
self.assertEqual("dataengine", all_datasources[1].datasource_type)
6869
self.assertEqual("description Sample", all_datasources[1].description)
6970
self.assertEqual("Sampledatasource", all_datasources[1].content_url)
71+
self.assertEqual(10240, all_datasources[1].size)
7072
self.assertEqual("2016-08-04T21:31:55Z", format_datetime(all_datasources[1].created_at))
7173
self.assertEqual("2016-08-04T21:31:55Z", format_datetime(all_datasources[1].updated_at))
7274
self.assertEqual("default", all_datasources[1].project_name)

test/test_workbook.py

+29
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
GET_EMPTY_XML = os.path.join(TEST_ASSET_DIR, "workbook_get_empty.xml")
2323
GET_INVALID_DATE_XML = os.path.join(TEST_ASSET_DIR, "workbook_get_invalid_date.xml")
2424
GET_XML = os.path.join(TEST_ASSET_DIR, "workbook_get.xml")
25+
ODATA_XML = os.path.join(TEST_ASSET_DIR, "odata_connection.xml")
2526
POPULATE_CONNECTIONS_XML = os.path.join(TEST_ASSET_DIR, "workbook_populate_connections.xml")
2627
POPULATE_PDF = os.path.join(TEST_ASSET_DIR, "populate_pdf.pdf")
2728
POPULATE_POWERPOINT = os.path.join(TEST_ASSET_DIR, "populate_powerpoint.pptx")
@@ -944,3 +945,31 @@ def test_bad_download_response(self) -> None:
944945
)
945946
file_path = self.server.workbooks.download("9dbd2263-16b5-46e1-9c43-a76bb8ab65fb", td)
946947
self.assertTrue(os.path.exists(file_path))
948+
949+
def test_odata_connection(self) -> None:
950+
self.baseurl = self.server.workbooks.baseurl
951+
workbook = TSC.WorkbookItem("project", "test")
952+
workbook._id = "06b944d2-959d-4604-9305-12323c95e70e"
953+
connection = TSC.ConnectionItem()
954+
url = "https://odata.website.com/TestODataEndpoint"
955+
connection.server_address = url
956+
connection._connection_type = "odata"
957+
connection._id = "17376070-64d1-4d17-acb4-a56e4b5b1768"
958+
959+
creds = TSC.ConnectionCredentials("", "", True)
960+
connection.connection_credentials = creds
961+
with open(ODATA_XML, "rb") as f:
962+
response_xml = f.read().decode("utf-8")
963+
964+
with requests_mock.mock() as m:
965+
m.put(f"{self.baseurl}/{workbook.id}/connections/{connection.id}", text=response_xml)
966+
self.server.workbooks.update_connection(workbook, connection)
967+
968+
history = m.request_history
969+
970+
request = history[0]
971+
xml = fromstring(request.body)
972+
xml_connection = xml.find(".//connection")
973+
974+
assert xml_connection is not None
975+
self.assertEqual(xml_connection.get("serverAddress"), url)

0 commit comments

Comments
 (0)