tableauserverclient 0.32__py3-none-any.whl → 0.33__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- tableauserverclient/__init__.py +10 -0
- tableauserverclient/_version.py +3 -3
- tableauserverclient/config.py +16 -4
- tableauserverclient/models/__init__.py +12 -0
- tableauserverclient/models/connection_item.py +4 -2
- tableauserverclient/models/database_item.py +6 -0
- tableauserverclient/models/flow_item.py +6 -6
- tableauserverclient/models/groupset_item.py +53 -0
- tableauserverclient/models/interval_item.py +27 -14
- tableauserverclient/models/job_item.py +18 -2
- tableauserverclient/models/linked_tasks_item.py +102 -0
- tableauserverclient/models/permissions_item.py +7 -4
- tableauserverclient/models/tableau_types.py +9 -7
- tableauserverclient/models/virtual_connection_item.py +77 -0
- tableauserverclient/server/endpoint/__init__.py +8 -0
- tableauserverclient/server/endpoint/auth_endpoint.py +3 -3
- tableauserverclient/server/endpoint/custom_views_endpoint.py +65 -4
- tableauserverclient/server/endpoint/databases_endpoint.py +21 -7
- tableauserverclient/server/endpoint/datasources_endpoint.py +105 -9
- tableauserverclient/server/endpoint/endpoint.py +32 -14
- tableauserverclient/server/endpoint/fileuploads_endpoint.py +2 -2
- tableauserverclient/server/endpoint/flow_runs_endpoint.py +44 -4
- tableauserverclient/server/endpoint/flows_endpoint.py +43 -6
- tableauserverclient/server/endpoint/groups_endpoint.py +82 -14
- tableauserverclient/server/endpoint/groupsets_endpoint.py +127 -0
- tableauserverclient/server/endpoint/jobs_endpoint.py +74 -7
- tableauserverclient/server/endpoint/linked_tasks_endpoint.py +45 -0
- tableauserverclient/server/endpoint/projects_endpoint.py +43 -0
- tableauserverclient/server/endpoint/resource_tagger.py +135 -3
- tableauserverclient/server/endpoint/tables_endpoint.py +19 -6
- tableauserverclient/server/endpoint/users_endpoint.py +39 -0
- tableauserverclient/server/endpoint/views_endpoint.py +94 -9
- tableauserverclient/server/endpoint/virtual_connections_endpoint.py +173 -0
- tableauserverclient/server/endpoint/workbooks_endpoint.py +91 -10
- tableauserverclient/server/pager.py +6 -7
- tableauserverclient/server/query.py +2 -1
- tableauserverclient/server/request_factory.py +178 -7
- tableauserverclient/server/request_options.py +4 -2
- tableauserverclient/server/server.py +8 -0
- {tableauserverclient-0.32.dist-info → tableauserverclient-0.33.dist-info}/METADATA +15 -15
- {tableauserverclient-0.32.dist-info → tableauserverclient-0.33.dist-info}/RECORD +45 -39
- {tableauserverclient-0.32.dist-info → tableauserverclient-0.33.dist-info}/WHEEL +1 -1
- {tableauserverclient-0.32.dist-info → tableauserverclient-0.33.dist-info}/LICENSE +0 -0
- {tableauserverclient-0.32.dist-info → tableauserverclient-0.33.dist-info}/LICENSE.versioneer +0 -0
- {tableauserverclient-0.32.dist-info → tableauserverclient-0.33.dist-info}/top_level.txt +0 -0
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import xml.etree.ElementTree as ET
|
|
2
|
-
from typing import Any, Dict, Iterable, List, Optional, Tuple, TYPE_CHECKING
|
|
2
|
+
from typing import Any, Callable, Dict, Iterable, List, Optional, Set, Tuple, TypeVar, TYPE_CHECKING, Union
|
|
3
|
+
|
|
4
|
+
from typing_extensions import ParamSpec
|
|
3
5
|
|
|
4
6
|
from requests.packages.urllib3.fields import RequestField
|
|
5
7
|
from requests.packages.urllib3.filepost import encode_multipart_formdata
|
|
8
|
+
from typing_extensions import Concatenate
|
|
6
9
|
|
|
7
10
|
from tableauserverclient.models import *
|
|
8
11
|
|
|
@@ -23,8 +26,12 @@ def _add_multipart(parts: Dict) -> Tuple[Any, str]:
|
|
|
23
26
|
return xml_request, content_type
|
|
24
27
|
|
|
25
28
|
|
|
26
|
-
|
|
27
|
-
|
|
29
|
+
T = TypeVar("T")
|
|
30
|
+
P = ParamSpec("P")
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def _tsrequest_wrapped(func: Callable[Concatenate[T, ET.Element, P], Any]) -> Callable[Concatenate[T, P], bytes]:
|
|
34
|
+
def wrapper(self: T, *args: P.args, **kwargs: P.kwargs) -> bytes:
|
|
28
35
|
xml_request = ET.Element("tsRequest")
|
|
29
36
|
func(self, xml_request, *args, **kwargs)
|
|
30
37
|
return ET.tostring(xml_request)
|
|
@@ -387,6 +394,28 @@ class GroupRequest(object):
|
|
|
387
394
|
user_element.attrib["id"] = user_id
|
|
388
395
|
return ET.tostring(xml_request)
|
|
389
396
|
|
|
397
|
+
@_tsrequest_wrapped
|
|
398
|
+
def add_users_req(self, xml_request: ET.Element, users: Iterable[Union[str, UserItem]]) -> bytes:
|
|
399
|
+
users_element = ET.SubElement(xml_request, "users")
|
|
400
|
+
for user in users:
|
|
401
|
+
user_element = ET.SubElement(users_element, "user")
|
|
402
|
+
if not (user_id := user.id if isinstance(user, UserItem) else user):
|
|
403
|
+
raise ValueError("User ID must be populated")
|
|
404
|
+
user_element.attrib["id"] = user_id
|
|
405
|
+
|
|
406
|
+
return ET.tostring(xml_request)
|
|
407
|
+
|
|
408
|
+
@_tsrequest_wrapped
|
|
409
|
+
def remove_users_req(self, xml_request: ET.Element, users: Iterable[Union[str, UserItem]]) -> bytes:
|
|
410
|
+
users_element = ET.SubElement(xml_request, "users")
|
|
411
|
+
for user in users:
|
|
412
|
+
user_element = ET.SubElement(users_element, "user")
|
|
413
|
+
if not (user_id := user.id if isinstance(user, UserItem) else user):
|
|
414
|
+
raise ValueError("User ID must be populated")
|
|
415
|
+
user_element.attrib["id"] = user_id
|
|
416
|
+
|
|
417
|
+
return ET.tostring(xml_request)
|
|
418
|
+
|
|
390
419
|
def create_local_req(self, group_item: GroupItem) -> bytes:
|
|
391
420
|
xml_request = ET.Element("tsRequest")
|
|
392
421
|
group_element = ET.SubElement(xml_request, "group")
|
|
@@ -839,6 +868,9 @@ class TableRequest(object):
|
|
|
839
868
|
return ET.tostring(xml_request)
|
|
840
869
|
|
|
841
870
|
|
|
871
|
+
content_types = Iterable[Union["ColumnItem", "DatabaseItem", "DatasourceItem", "FlowItem", "TableItem", "WorkbookItem"]]
|
|
872
|
+
|
|
873
|
+
|
|
842
874
|
class TagRequest(object):
|
|
843
875
|
def add_req(self, tag_set):
|
|
844
876
|
xml_request = ET.Element("tsRequest")
|
|
@@ -848,6 +880,22 @@ class TagRequest(object):
|
|
|
848
880
|
tag_element.attrib["label"] = tag
|
|
849
881
|
return ET.tostring(xml_request)
|
|
850
882
|
|
|
883
|
+
@_tsrequest_wrapped
|
|
884
|
+
def batch_create(self, element: ET.Element, tags: Set[str], content: content_types) -> bytes:
|
|
885
|
+
tag_batch = ET.SubElement(element, "tagBatch")
|
|
886
|
+
tags_element = ET.SubElement(tag_batch, "tags")
|
|
887
|
+
for tag in tags:
|
|
888
|
+
tag_element = ET.SubElement(tags_element, "tag")
|
|
889
|
+
tag_element.attrib["label"] = tag
|
|
890
|
+
contents_element = ET.SubElement(tag_batch, "contents")
|
|
891
|
+
for item in content:
|
|
892
|
+
content_element = ET.SubElement(contents_element, "content")
|
|
893
|
+
if item.id is None:
|
|
894
|
+
raise ValueError(f"Item {item} must have an ID to be tagged.")
|
|
895
|
+
content_element.attrib["id"] = item.id
|
|
896
|
+
|
|
897
|
+
return ET.tostring(element)
|
|
898
|
+
|
|
851
899
|
|
|
852
900
|
class UserRequest(object):
|
|
853
901
|
def update_req(self, user_item: UserItem, password: Optional[str]) -> bytes:
|
|
@@ -1014,14 +1062,17 @@ class WorkbookRequest(object):
|
|
|
1014
1062
|
return _add_multipart(parts)
|
|
1015
1063
|
|
|
1016
1064
|
@_tsrequest_wrapped
|
|
1017
|
-
def embedded_extract_req(
|
|
1065
|
+
def embedded_extract_req(
|
|
1066
|
+
self, xml_request: ET.Element, include_all: bool = True, datasources: Optional[Iterable[DatasourceItem]] = None
|
|
1067
|
+
) -> None:
|
|
1018
1068
|
list_element = ET.SubElement(xml_request, "datasources")
|
|
1019
1069
|
if include_all:
|
|
1020
1070
|
list_element.attrib["includeAll"] = "true"
|
|
1021
1071
|
elif datasources:
|
|
1022
1072
|
for datasource_item in datasources:
|
|
1023
1073
|
datasource_element = ET.SubElement(list_element, "datasource")
|
|
1024
|
-
|
|
1074
|
+
if (id_ := datasource_item.id) is not None:
|
|
1075
|
+
datasource_element.attrib["id"] = id_
|
|
1025
1076
|
|
|
1026
1077
|
|
|
1027
1078
|
class Connection(object):
|
|
@@ -1049,7 +1100,7 @@ class Connection(object):
|
|
|
1049
1100
|
|
|
1050
1101
|
class TaskRequest(object):
|
|
1051
1102
|
@_tsrequest_wrapped
|
|
1052
|
-
def run_req(self, xml_request, task_item):
|
|
1103
|
+
def run_req(self, xml_request: ET.Element, task_item: Any) -> None:
|
|
1053
1104
|
# Send an empty tsRequest
|
|
1054
1105
|
pass
|
|
1055
1106
|
|
|
@@ -1186,7 +1237,7 @@ class SubscriptionRequest(object):
|
|
|
1186
1237
|
|
|
1187
1238
|
class EmptyRequest(object):
|
|
1188
1239
|
@_tsrequest_wrapped
|
|
1189
|
-
def empty_req(self, xml_request):
|
|
1240
|
+
def empty_req(self, xml_request: ET.Element) -> None:
|
|
1190
1241
|
pass
|
|
1191
1242
|
|
|
1192
1243
|
|
|
@@ -1245,6 +1296,124 @@ class CustomViewRequest(object):
|
|
|
1245
1296
|
if custom_view_item.name is not None:
|
|
1246
1297
|
updating_element.attrib["name"] = custom_view_item.name
|
|
1247
1298
|
|
|
1299
|
+
@_tsrequest_wrapped
|
|
1300
|
+
def _publish_xml(self, xml_request: ET.Element, custom_view_item: CustomViewItem) -> bytes:
|
|
1301
|
+
custom_view_element = ET.SubElement(xml_request, "customView")
|
|
1302
|
+
if (name := custom_view_item.name) is not None:
|
|
1303
|
+
custom_view_element.attrib["name"] = name
|
|
1304
|
+
else:
|
|
1305
|
+
raise ValueError(f"Custom View Item missing name: {custom_view_item}")
|
|
1306
|
+
if (shared := custom_view_item.shared) is not None:
|
|
1307
|
+
custom_view_element.attrib["shared"] = str(shared).lower()
|
|
1308
|
+
else:
|
|
1309
|
+
raise ValueError(f"Custom View Item missing shared: {custom_view_item}")
|
|
1310
|
+
if (owner := custom_view_item.owner) is not None:
|
|
1311
|
+
owner_element = ET.SubElement(custom_view_element, "owner")
|
|
1312
|
+
if (owner_id := owner.id) is not None:
|
|
1313
|
+
owner_element.attrib["id"] = owner_id
|
|
1314
|
+
else:
|
|
1315
|
+
raise ValueError(f"Custom View Item owner missing id: {owner}")
|
|
1316
|
+
else:
|
|
1317
|
+
raise ValueError(f"Custom View Item missing owner: {custom_view_item}")
|
|
1318
|
+
if (workbook := custom_view_item.workbook) is not None:
|
|
1319
|
+
workbook_element = ET.SubElement(custom_view_element, "workbook")
|
|
1320
|
+
if (workbook_id := workbook.id) is not None:
|
|
1321
|
+
workbook_element.attrib["id"] = workbook_id
|
|
1322
|
+
else:
|
|
1323
|
+
raise ValueError(f"Custom View Item workbook missing id: {workbook}")
|
|
1324
|
+
else:
|
|
1325
|
+
raise ValueError(f"Custom View Item missing workbook: {custom_view_item}")
|
|
1326
|
+
|
|
1327
|
+
return ET.tostring(xml_request)
|
|
1328
|
+
|
|
1329
|
+
def publish_req_chunked(self, custom_view_item: CustomViewItem):
|
|
1330
|
+
xml_request = self._publish_xml(custom_view_item)
|
|
1331
|
+
parts = {"request_payload": ("", xml_request, "text/xml")}
|
|
1332
|
+
return _add_multipart(parts)
|
|
1333
|
+
|
|
1334
|
+
def publish_req(self, custom_view_item: CustomViewItem, filename: str, file_contents: bytes):
|
|
1335
|
+
xml_request = self._publish_xml(custom_view_item)
|
|
1336
|
+
parts = {
|
|
1337
|
+
"request_payload": ("", xml_request, "text/xml"),
|
|
1338
|
+
"tableau_customview": (filename, file_contents, "application/octet-stream"),
|
|
1339
|
+
}
|
|
1340
|
+
return _add_multipart(parts)
|
|
1341
|
+
|
|
1342
|
+
|
|
1343
|
+
class GroupSetRequest:
|
|
1344
|
+
@_tsrequest_wrapped
|
|
1345
|
+
def create_request(self, xml_request: ET.Element, group_set_item: "GroupSetItem") -> bytes:
|
|
1346
|
+
group_set_element = ET.SubElement(xml_request, "groupSet")
|
|
1347
|
+
if group_set_item.name is not None:
|
|
1348
|
+
group_set_element.attrib["name"] = group_set_item.name
|
|
1349
|
+
return ET.tostring(xml_request)
|
|
1350
|
+
|
|
1351
|
+
@_tsrequest_wrapped
|
|
1352
|
+
def update_request(self, xml_request: ET.Element, group_set_item: "GroupSetItem") -> bytes:
|
|
1353
|
+
group_set_element = ET.SubElement(xml_request, "groupSet")
|
|
1354
|
+
if group_set_item.name is not None:
|
|
1355
|
+
group_set_element.attrib["name"] = group_set_item.name
|
|
1356
|
+
return ET.tostring(xml_request)
|
|
1357
|
+
|
|
1358
|
+
|
|
1359
|
+
class VirtualConnectionRequest:
|
|
1360
|
+
@_tsrequest_wrapped
|
|
1361
|
+
def update_db_connection(self, xml_request: ET.Element, connection_item: ConnectionItem) -> bytes:
|
|
1362
|
+
connection_element = ET.SubElement(xml_request, "connection")
|
|
1363
|
+
if connection_item.server_address is not None:
|
|
1364
|
+
connection_element.attrib["serverAddress"] = connection_item.server_address
|
|
1365
|
+
if connection_item.server_port is not None:
|
|
1366
|
+
connection_element.attrib["serverPort"] = str(connection_item.server_port)
|
|
1367
|
+
if connection_item.username is not None:
|
|
1368
|
+
connection_element.attrib["userName"] = connection_item.username
|
|
1369
|
+
if connection_item.password is not None:
|
|
1370
|
+
connection_element.attrib["password"] = connection_item.password
|
|
1371
|
+
|
|
1372
|
+
return ET.tostring(xml_request)
|
|
1373
|
+
|
|
1374
|
+
@_tsrequest_wrapped
|
|
1375
|
+
def update(self, xml_request: ET.Element, virtual_connection: VirtualConnectionItem) -> bytes:
|
|
1376
|
+
vc_element = ET.SubElement(xml_request, "virtualConnection")
|
|
1377
|
+
if virtual_connection.name is not None:
|
|
1378
|
+
vc_element.attrib["name"] = virtual_connection.name
|
|
1379
|
+
if virtual_connection.is_certified is not None:
|
|
1380
|
+
vc_element.attrib["isCertified"] = str(virtual_connection.is_certified).lower()
|
|
1381
|
+
if virtual_connection.certification_note is not None:
|
|
1382
|
+
vc_element.attrib["certificationNote"] = virtual_connection.certification_note
|
|
1383
|
+
if virtual_connection.project_id is not None:
|
|
1384
|
+
project_element = ET.SubElement(vc_element, "project")
|
|
1385
|
+
project_element.attrib["id"] = virtual_connection.project_id
|
|
1386
|
+
if virtual_connection.owner_id is not None:
|
|
1387
|
+
owner_element = ET.SubElement(vc_element, "owner")
|
|
1388
|
+
owner_element.attrib["id"] = virtual_connection.owner_id
|
|
1389
|
+
|
|
1390
|
+
return ET.tostring(xml_request)
|
|
1391
|
+
|
|
1392
|
+
@_tsrequest_wrapped
|
|
1393
|
+
def publish(self, xml_request: ET.Element, virtual_connection: VirtualConnectionItem, content: str) -> bytes:
|
|
1394
|
+
vc_element = ET.SubElement(xml_request, "virtualConnection")
|
|
1395
|
+
if virtual_connection.name is not None:
|
|
1396
|
+
vc_element.attrib["name"] = virtual_connection.name
|
|
1397
|
+
else:
|
|
1398
|
+
raise ValueError("Virtual Connection must have a name.")
|
|
1399
|
+
if virtual_connection.project_id is not None:
|
|
1400
|
+
project_element = ET.SubElement(vc_element, "project")
|
|
1401
|
+
project_element.attrib["id"] = virtual_connection.project_id
|
|
1402
|
+
else:
|
|
1403
|
+
raise ValueError("Virtual Connection must have a project id.")
|
|
1404
|
+
if virtual_connection.owner_id is not None:
|
|
1405
|
+
owner_element = ET.SubElement(vc_element, "owner")
|
|
1406
|
+
owner_element.attrib["id"] = virtual_connection.owner_id
|
|
1407
|
+
else:
|
|
1408
|
+
raise ValueError("Virtual Connection must have an owner id.")
|
|
1409
|
+
if content is not None:
|
|
1410
|
+
content_element = ET.SubElement(vc_element, "content")
|
|
1411
|
+
content_element.text = content
|
|
1412
|
+
else:
|
|
1413
|
+
raise ValueError("Virtual Connection must have content.")
|
|
1414
|
+
|
|
1415
|
+
return ET.tostring(xml_request)
|
|
1416
|
+
|
|
1248
1417
|
|
|
1249
1418
|
class RequestFactory(object):
|
|
1250
1419
|
Auth = AuthRequest()
|
|
@@ -1261,6 +1430,7 @@ class RequestFactory(object):
|
|
|
1261
1430
|
Flow = FlowRequest()
|
|
1262
1431
|
FlowTask = FlowTaskRequest()
|
|
1263
1432
|
Group = GroupRequest()
|
|
1433
|
+
GroupSet = GroupSetRequest()
|
|
1264
1434
|
Metric = MetricRequest()
|
|
1265
1435
|
Permission = PermissionRequest()
|
|
1266
1436
|
Project = ProjectRequest()
|
|
@@ -1271,5 +1441,6 @@ class RequestFactory(object):
|
|
|
1271
1441
|
Tag = TagRequest()
|
|
1272
1442
|
Task = TaskRequest()
|
|
1273
1443
|
User = UserRequest()
|
|
1444
|
+
VirtualConnection = VirtualConnectionRequest()
|
|
1274
1445
|
Workbook = WorkbookRequest()
|
|
1275
1446
|
Webhook = WebhookRequest()
|
|
@@ -2,6 +2,7 @@ import sys
|
|
|
2
2
|
|
|
3
3
|
from typing_extensions import Self
|
|
4
4
|
|
|
5
|
+
from tableauserverclient.config import config
|
|
5
6
|
from tableauserverclient.models.property_decorators import property_is_int
|
|
6
7
|
import logging
|
|
7
8
|
|
|
@@ -38,6 +39,7 @@ class RequestOptions(RequestOptionsBase):
|
|
|
38
39
|
LessThanOrEqual = "lte"
|
|
39
40
|
In = "in"
|
|
40
41
|
Has = "has"
|
|
42
|
+
CaseInsensitiveEquals = "cieq"
|
|
41
43
|
|
|
42
44
|
class Field:
|
|
43
45
|
Args = "args"
|
|
@@ -115,9 +117,9 @@ class RequestOptions(RequestOptionsBase):
|
|
|
115
117
|
Desc = "desc"
|
|
116
118
|
Asc = "asc"
|
|
117
119
|
|
|
118
|
-
def __init__(self, pagenumber=1, pagesize=
|
|
120
|
+
def __init__(self, pagenumber=1, pagesize=None):
|
|
119
121
|
self.pagenumber = pagenumber
|
|
120
|
-
self.pagesize = pagesize
|
|
122
|
+
self.pagesize = pagesize or config.PAGE_SIZE
|
|
121
123
|
self.sort = set()
|
|
122
124
|
self.filter = set()
|
|
123
125
|
|
|
@@ -33,6 +33,10 @@ from tableauserverclient.server.endpoint import (
|
|
|
33
33
|
Metrics,
|
|
34
34
|
Endpoint,
|
|
35
35
|
CustomViews,
|
|
36
|
+
LinkedTasks,
|
|
37
|
+
GroupSets,
|
|
38
|
+
Tags,
|
|
39
|
+
VirtualConnections,
|
|
36
40
|
)
|
|
37
41
|
from tableauserverclient.server.exceptions import (
|
|
38
42
|
ServerInfoEndpointNotFoundError,
|
|
@@ -99,6 +103,10 @@ class Server(object):
|
|
|
99
103
|
self.flow_runs = FlowRuns(self)
|
|
100
104
|
self.metrics = Metrics(self)
|
|
101
105
|
self.custom_views = CustomViews(self)
|
|
106
|
+
self.linked_tasks = LinkedTasks(self)
|
|
107
|
+
self.group_sets = GroupSets(self)
|
|
108
|
+
self.tags = Tags(self)
|
|
109
|
+
self.virtual_connections = VirtualConnections(self)
|
|
102
110
|
|
|
103
111
|
self._session = self._session_factory()
|
|
104
112
|
self._http_options = dict() # must set this before making a server call
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: tableauserverclient
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.33
|
|
4
4
|
Summary: A Python module for working with the Tableau Server REST API.
|
|
5
5
|
Author-email: Tableau <github@tableau.com>
|
|
6
6
|
License: The MIT License (MIT)
|
|
@@ -37,19 +37,19 @@ Requires-Python: >=3.7
|
|
|
37
37
|
Description-Content-Type: text/markdown
|
|
38
38
|
License-File: LICENSE
|
|
39
39
|
License-File: LICENSE.versioneer
|
|
40
|
-
Requires-Dist: defusedxml
|
|
41
|
-
Requires-Dist: packaging
|
|
42
|
-
Requires-Dist: requests
|
|
43
|
-
Requires-Dist: urllib3
|
|
44
|
-
Requires-Dist: typing-extensions
|
|
40
|
+
Requires-Dist: defusedxml>=0.7.1
|
|
41
|
+
Requires-Dist: packaging>=23.1
|
|
42
|
+
Requires-Dist: requests>=2.31
|
|
43
|
+
Requires-Dist: urllib3==2.2.2
|
|
44
|
+
Requires-Dist: typing-extensions>=4.0.1
|
|
45
45
|
Provides-Extra: test
|
|
46
|
-
Requires-Dist: black
|
|
47
|
-
Requires-Dist: build
|
|
48
|
-
Requires-Dist: mypy
|
|
49
|
-
Requires-Dist: pytest
|
|
50
|
-
Requires-Dist: pytest-cov
|
|
51
|
-
Requires-Dist: pytest-subtests
|
|
52
|
-
Requires-Dist: requests-mock
|
|
46
|
+
Requires-Dist: black==23.7; extra == "test"
|
|
47
|
+
Requires-Dist: build; extra == "test"
|
|
48
|
+
Requires-Dist: mypy==1.4; extra == "test"
|
|
49
|
+
Requires-Dist: pytest>=7.0; extra == "test"
|
|
50
|
+
Requires-Dist: pytest-cov; extra == "test"
|
|
51
|
+
Requires-Dist: pytest-subtests; extra == "test"
|
|
52
|
+
Requires-Dist: requests-mock<2.0,>=1.0; extra == "test"
|
|
53
53
|
|
|
54
54
|
# Tableau Server Client (Python)
|
|
55
55
|
|
|
@@ -62,14 +62,14 @@ Use the Tableau Server Client (TSC) library to increase your productivity as you
|
|
|
62
62
|
* Create users and groups.
|
|
63
63
|
* Query projects, sites, and more.
|
|
64
64
|
|
|
65
|
-
This repository contains Python source code for the library and sample files showing how to use it. As of
|
|
65
|
+
This repository contains Python source code for the library and sample files showing how to use it. As of September 2024, support for Python 3.7 and 3.8 will be dropped - support for older versions of Python aims to match https://devguide.python.org/versions/
|
|
66
66
|
|
|
67
67
|
To see sample code that works directly with the REST API (in Java, Python, or Postman), visit the [REST API Samples](https://github.com/tableau/rest-api-samples) repo.
|
|
68
68
|
|
|
69
69
|
For more information on installing and using TSC, see the documentation:
|
|
70
70
|
<https://tableau.github.io/server-client-python/docs/>
|
|
71
71
|
|
|
72
|
-
|
|
72
|
+
To contribute, see our [Developer Guide](https://tableau.github.io/server-client-python/docs/dev-guide). A list of all our contributors to date is in [CONTRIBUTORS.md].
|
|
73
73
|
|
|
74
74
|
## License
|
|
75
75
|
[](https://app.fossa.com/projects/git%2Bgithub.com%2Ftableau%2Fserver-client-python?ref=badge_large)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
tableauserverclient/__init__.py,sha256=
|
|
2
|
-
tableauserverclient/_version.py,sha256=
|
|
3
|
-
tableauserverclient/config.py,sha256=
|
|
1
|
+
tableauserverclient/__init__.py,sha256=S4jtf2A0eOd9AP5BHwpZPfpmZyo7zSUABERV3DcKNLI,2619
|
|
2
|
+
tableauserverclient/_version.py,sha256=uDb1hbg0H8M6ypXC64xV9HVAlKx6xhunFG5fBAtkVz4,496
|
|
3
|
+
tableauserverclient/config.py,sha256=oyX-CcsDNOyzr8tOvJgHYUF8VRuHeEK9UzbnYDsdNns,617
|
|
4
4
|
tableauserverclient/datetime_helpers.py,sha256=_-gWz5I2_KHT5AzW_boD8meH6loTTKdK-_62h1MA6ko,884
|
|
5
5
|
tableauserverclient/exponential_backoff.py,sha256=HtAfbbVnYtiOe2_ZzKqZmsml40EDZBaC3bttif5qeG8,1474
|
|
6
6
|
tableauserverclient/filesys_helpers.py,sha256=hosTm9fpc9B9_VCDcAuyHA0A-f-MWs9_2utyRweuZ5I,1667
|
|
@@ -10,28 +10,30 @@ tableauserverclient/helpers/__init__.py,sha256=llpqF9zV5dsP5hQt8dyop33Op5OzGmxW0
|
|
|
10
10
|
tableauserverclient/helpers/headers.py,sha256=Pg-ZWSgV2Yp813BV1Tzo8F2Hn4P01zscla2RRM4yqNk,411
|
|
11
11
|
tableauserverclient/helpers/logging.py,sha256=5q_oR3wERHVXFXY6XDnLYML5-HdAPJTmqhH9IZg4VfY,113
|
|
12
12
|
tableauserverclient/helpers/strings.py,sha256=HRTP31HIdD3gFxDDHuBsmOl_8cLdh8fa3xLALgYsUAQ,1563
|
|
13
|
-
tableauserverclient/models/__init__.py,sha256=
|
|
13
|
+
tableauserverclient/models/__init__.py,sha256=bU4eaOQ4I9h_JYn7IbhCZhHbMVvxdSUhMJeHg80apYA,4051
|
|
14
14
|
tableauserverclient/models/column_item.py,sha256=gV2r7xOVmcn9UnMXFOe9_ORZ85oha1KtIH-crKUhgN4,1972
|
|
15
15
|
tableauserverclient/models/connection_credentials.py,sha256=8Wa8B_-cB3INFUup-Pyd5znsUD5opgYYH5TfipCzKTU,1559
|
|
16
|
-
tableauserverclient/models/connection_item.py,sha256=
|
|
16
|
+
tableauserverclient/models/connection_item.py,sha256=I-jCT8f1sb7D7jkdM_BEBxd5oZFYBRYDTY6dz2vhmE8,4821
|
|
17
17
|
tableauserverclient/models/custom_view_item.py,sha256=Gr2lYgBU1zUfCoaXHhqTzWDspmL33UqOxlt48Y8yaGg,5782
|
|
18
18
|
tableauserverclient/models/data_acceleration_report_item.py,sha256=5Z18-fppR_lnAyPKHwxi4gOP6kqcYX3Q3RdwiD4Zy94,3402
|
|
19
19
|
tableauserverclient/models/data_alert_item.py,sha256=sJpncsKY1BY-tFJKDpX7xaHy6aGvELWrorsILJxr3lI,6458
|
|
20
20
|
tableauserverclient/models/data_freshness_policy_item.py,sha256=p5iyGHl-juDM3ARl9tWr3i_LnpzalxUTRoDBP6FdTMo,7639
|
|
21
|
-
tableauserverclient/models/database_item.py,sha256=
|
|
21
|
+
tableauserverclient/models/database_item.py,sha256=bJN4AmV4033xwWVm4yHZ8NDQWo2WpbAHs-994juwVZQ,8266
|
|
22
22
|
tableauserverclient/models/datasource_item.py,sha256=a0k9uOVwPWZeCS_5jq278BUYYF5uaZMxUqOH4GTC5sM,12407
|
|
23
23
|
tableauserverclient/models/dqw_item.py,sha256=MFpxSP6vSzpjh5GLNrom--Sbi8iLwuGLuAda8KHiIa8,3718
|
|
24
24
|
tableauserverclient/models/exceptions.py,sha256=pQu5DS4jNMT9A0wEBWv2vANAQU1vgNpFatVr8sGE4zk,105
|
|
25
25
|
tableauserverclient/models/favorites_item.py,sha256=iVC39Qx_534spqPIv-g6grQMWBNj7LgE0ViCI3qiQ9g,3322
|
|
26
26
|
tableauserverclient/models/fileupload_item.py,sha256=tx3LfgRxVqeHGpCN6kTDPkdBY5i1H-u1RVaPf0hQx_4,750
|
|
27
|
-
tableauserverclient/models/flow_item.py,sha256=
|
|
27
|
+
tableauserverclient/models/flow_item.py,sha256=dfvgaWFTepN9VTOpgAc32nq2AZfCkEog43VsJJbcP00,7476
|
|
28
28
|
tableauserverclient/models/flow_run_item.py,sha256=pwJNz0m7l--Sb6z0o83ebWfAmTVFYSr-0apMxHWt0Vs,3139
|
|
29
29
|
tableauserverclient/models/group_item.py,sha256=1KP_KmIG1veJJGyte82aFvMAiU_tvzYtaP2vLEReLoo,3621
|
|
30
|
-
tableauserverclient/models/
|
|
31
|
-
tableauserverclient/models/
|
|
30
|
+
tableauserverclient/models/groupset_item.py,sha256=oKpsdfAz9NaqyAZwZHAIMGOmzUVEwke5sn0lBn7Omxo,1897
|
|
31
|
+
tableauserverclient/models/interval_item.py,sha256=fxTLxLdR-hVewS-a961n-YfuUY46XyhpHfxFyTBgBgU,9177
|
|
32
|
+
tableauserverclient/models/job_item.py,sha256=hlGsYdXO0al4OYxZ8fVxaWmm7eJydIQzZEyeC-_RG8c,9253
|
|
33
|
+
tableauserverclient/models/linked_tasks_item.py,sha256=t5BdLyCdD0FxFRu_BRWu5UZWp6qiEiFKswSw4wE3ZAU,3812
|
|
32
34
|
tableauserverclient/models/metric_item.py,sha256=Zrzi_Un43p2jzE_4OhetxhjfeSUYzotMfm8Hjd5WOhI,5397
|
|
33
35
|
tableauserverclient/models/pagination_item.py,sha256=Hdr2EIKWkXfrjWOr-Ao_vzQTWB2akUfxxtaupFKLrlQ,1432
|
|
34
|
-
tableauserverclient/models/permissions_item.py,sha256=
|
|
36
|
+
tableauserverclient/models/permissions_item.py,sha256=MDZ7DJ6TfIcXPKnwscb7k7BJopw91uccirxqS4QN81M,6099
|
|
35
37
|
tableauserverclient/models/project_item.py,sha256=c5c5IujaYASX7-pEvDi-Qg-4xb2QVQ_F1dOUNSjQQk4,6946
|
|
36
38
|
tableauserverclient/models/property_decorators.py,sha256=W5EtN7bqDHrpLQF63i1cGOhPUJi0RzMJ7qmIlJVrGuE,4711
|
|
37
39
|
tableauserverclient/models/reference_item.py,sha256=mHMPMeTGx4yor9QEFq_IGwQUtkn2mjEO0O5bptHKRmo,751
|
|
@@ -42,59 +44,63 @@ tableauserverclient/models/site_item.py,sha256=xvXpsR0eEz2ypS-94KJTMS-gusHV1bLom
|
|
|
42
44
|
tableauserverclient/models/subscription_item.py,sha256=XkQiAi_gWPBnxtTaB8TgrFa-IDVDtai9H00Ilay0T64,4744
|
|
43
45
|
tableauserverclient/models/table_item.py,sha256=WgXrHCgmA5djpA7k2tNuZ8A3PPK6GEKfj9RQZ27RsNk,4583
|
|
44
46
|
tableauserverclient/models/tableau_auth.py,sha256=2ntxM2jq-GZ6qS4eLw2uTnXT8gROb03sjdJeIx8jYCw,3824
|
|
45
|
-
tableauserverclient/models/tableau_types.py,sha256=
|
|
47
|
+
tableauserverclient/models/tableau_types.py,sha256=jPM9AKw1O-bVcgoFAl7YWFTj8pFVxsk0SsMrIqdKq9g,1226
|
|
46
48
|
tableauserverclient/models/tag_item.py,sha256=mVfJGZG8PspPM8hBxX38heEQ_Rnp5sSwfwWdLNA-UV0,619
|
|
47
49
|
tableauserverclient/models/target.py,sha256=dVc1SHwo9ZASR8250MhAPODXX_G5UqA4BnK8hykRE6E,263
|
|
48
50
|
tableauserverclient/models/task_item.py,sha256=EHVJo6NyORC_NZ0NFZTt8ylRBCeO6LFxI1Ubf15L2zo,3775
|
|
49
51
|
tableauserverclient/models/user_item.py,sha256=vaQD3nvU7bJVD6t0nkWQFse8UDz8HTp8wh_6WmCjKtM,15776
|
|
50
52
|
tableauserverclient/models/view_item.py,sha256=OcZqrCJt0cjz1bSUUdLIseOYeDfo4ji4UWkv11el6Bc,8106
|
|
53
|
+
tableauserverclient/models/virtual_connection_item.py,sha256=w683i3SSKzzLiH8nsAUAUBXIDX3OaM4Jjf-wMw6KaTU,3342
|
|
51
54
|
tableauserverclient/models/webhook_item.py,sha256=LLf2HQ2Y50Rw-c4dSYyv6MXLbXdij9Iyy261gu9zpv4,2650
|
|
52
55
|
tableauserverclient/models/workbook_item.py,sha256=w6RVKOPFJ9NEmz7OG0SuKw_8FrTE4rWLKw4JkHl1lag,14118
|
|
53
56
|
tableauserverclient/server/__init__.py,sha256=7QNKHgRznMbvoxB3q0R3Sth1ujesgkNmvmjjdlSSz8E,1846
|
|
54
57
|
tableauserverclient/server/exceptions.py,sha256=l-O4lcoEeXJC7fLWUanIcZM_Mf8m54uK3NQuKNj3RCg,183
|
|
55
58
|
tableauserverclient/server/filter.py,sha256=WZ_dIBuADRZf8VTYcRgn1rulSGUOJq8_uUltq05KkRI,1119
|
|
56
|
-
tableauserverclient/server/pager.py,sha256=
|
|
57
|
-
tableauserverclient/server/query.py,sha256=
|
|
58
|
-
tableauserverclient/server/request_factory.py,sha256=
|
|
59
|
-
tableauserverclient/server/request_options.py,sha256=
|
|
60
|
-
tableauserverclient/server/server.py,sha256=
|
|
59
|
+
tableauserverclient/server/pager.py,sha256=4ebEBA6RYSLJfUXpYfSPxb2IIUQsXn4ASTg6-wug54A,2684
|
|
60
|
+
tableauserverclient/server/query.py,sha256=F4m08Re1s8GeSrD2aFbS8INVHoELt--NcbrGY1sd5dk,6830
|
|
61
|
+
tableauserverclient/server/request_factory.py,sha256=gELn4j9zv-Y69qnO61GBUhFXyGrmu4yGGJSZpDkRGzo,71734
|
|
62
|
+
tableauserverclient/server/request_options.py,sha256=dsi7a2AtoxuRowVTx6KqbiwcX4IOk_oPKP4bO6SHCwA,10088
|
|
63
|
+
tableauserverclient/server/server.py,sha256=4AWEyQpC5-TNCUBG7R2Ex9U1VDE5ykjrT77dtknpO5M,8789
|
|
61
64
|
tableauserverclient/server/sort.py,sha256=ikndqXW2r2FeacJzybC2TVcJGn4ktviWgXwPyK-AX-0,208
|
|
62
|
-
tableauserverclient/server/endpoint/__init__.py,sha256=
|
|
63
|
-
tableauserverclient/server/endpoint/auth_endpoint.py,sha256=
|
|
64
|
-
tableauserverclient/server/endpoint/custom_views_endpoint.py,sha256=
|
|
65
|
+
tableauserverclient/server/endpoint/__init__.py,sha256=MpttkNENWAiXS2QigwZMfWG6PnsB05QSFK4-OIR3CaQ,3101
|
|
66
|
+
tableauserverclient/server/endpoint/auth_endpoint.py,sha256=VGdWEokoN6rIWgGPlNP2IL3pQOKKaMOWdZJEukQ-lHo,5234
|
|
67
|
+
tableauserverclient/server/endpoint/custom_views_endpoint.py,sha256=PxoKTSwJoTu8UP-8QwidvOWx_9cN5q2vZM-q7DuFrsA,7227
|
|
65
68
|
tableauserverclient/server/endpoint/data_acceleration_report_endpoint.py,sha256=nfC2gXoCke-YXGTiMWGDRBK_lDlLa9Y6hts7w3Zs8cI,1170
|
|
66
69
|
tableauserverclient/server/endpoint/data_alert_endpoint.py,sha256=c6-ICGRVDRQN7ClAgCeJsk6JK4HyBvtQGQVLOzNc4eo,5358
|
|
67
|
-
tableauserverclient/server/endpoint/databases_endpoint.py,sha256=
|
|
68
|
-
tableauserverclient/server/endpoint/datasources_endpoint.py,sha256=
|
|
70
|
+
tableauserverclient/server/endpoint/databases_endpoint.py,sha256=D2vnUfI6qWY96BO7-Pv6Phv3P7UWdJnj9pO98bM5Bgk,5794
|
|
71
|
+
tableauserverclient/server/endpoint/datasources_endpoint.py,sha256=LR3W9s_qYI05a0zGVp1WEC01G4xwCWBeYPvT2rL_ZRY,23156
|
|
69
72
|
tableauserverclient/server/endpoint/default_permissions_endpoint.py,sha256=HQSYPIJwVCimuWo4YGYvsc41_-rweLHmJ-tQrWdH-Y8,4386
|
|
70
73
|
tableauserverclient/server/endpoint/dqw_endpoint.py,sha256=TvzjonvIiGtp4EisoBKms1lHOkVTjagQACw6unyY9_8,2418
|
|
71
|
-
tableauserverclient/server/endpoint/endpoint.py,sha256=
|
|
74
|
+
tableauserverclient/server/endpoint/endpoint.py,sha256=o3PxB3QVewNjoIBNNipTGtabXDH8lXJawM97lvnrdW8,14203
|
|
72
75
|
tableauserverclient/server/endpoint/exceptions.py,sha256=fh4fFYasqiKd3EPTxriVsmLkRL24wz9UvX94BMRfyLY,2534
|
|
73
76
|
tableauserverclient/server/endpoint/favorites_endpoint.py,sha256=Tb29-sW3E_sjhWRUjZlPUbwDM9c9dR_xK3TlWN33lxw,6736
|
|
74
|
-
tableauserverclient/server/endpoint/fileuploads_endpoint.py,sha256=
|
|
75
|
-
tableauserverclient/server/endpoint/flow_runs_endpoint.py,sha256=
|
|
77
|
+
tableauserverclient/server/endpoint/fileuploads_endpoint.py,sha256=OP2sNNm6lxuBl6NajGgrZRyNQIA4E95ZxlqksAbd8nc,2553
|
|
78
|
+
tableauserverclient/server/endpoint/flow_runs_endpoint.py,sha256=Wm-n9ZO3poQKdtmPDTxzUwitJHQN-BVldzcSQTAA4uI,4923
|
|
76
79
|
tableauserverclient/server/endpoint/flow_task_endpoint.py,sha256=j3snbRiYAPkI3FwhGG-CxKogHXP3SY59ep74YPrutpw,1113
|
|
77
|
-
tableauserverclient/server/endpoint/flows_endpoint.py,sha256=
|
|
78
|
-
tableauserverclient/server/endpoint/groups_endpoint.py,sha256=
|
|
79
|
-
tableauserverclient/server/endpoint/
|
|
80
|
+
tableauserverclient/server/endpoint/flows_endpoint.py,sha256=KET9TbLja2lXfD0VzO6z27k3PXRYFKTktsSefalOSlU,14324
|
|
81
|
+
tableauserverclient/server/endpoint/groups_endpoint.py,sha256=RJEWitdI_4nqHZCETDNJcNS58g9qXfBtvbZLLifax2s,9134
|
|
82
|
+
tableauserverclient/server/endpoint/groupsets_endpoint.py,sha256=h0rKEdxHf16wlOgpR6zdT9h2EqjQJRhsc1ZPXGIIao8,5598
|
|
83
|
+
tableauserverclient/server/endpoint/jobs_endpoint.py,sha256=-sclTGTQvJ8DXruKjk-KVZzsXpZcLJd1WfvrCC1SNKk,5705
|
|
84
|
+
tableauserverclient/server/endpoint/linked_tasks_endpoint.py,sha256=tlTVWgXtMzNbIU0Bbh8BxxbHz_xi7q4lK0Qtt6BVOlc,2275
|
|
80
85
|
tableauserverclient/server/endpoint/metadata_endpoint.py,sha256=Fqf8M3g8_L1hAWT5Ev3TJqv1F51SBLxcrO1xCbGDvik,5246
|
|
81
86
|
tableauserverclient/server/endpoint/metrics_endpoint.py,sha256=BjdtazZhSpJdspomT9Seyzxy0U7h1Uamui2DQo7u4Xc,3276
|
|
82
87
|
tableauserverclient/server/endpoint/permissions_endpoint.py,sha256=K-AZ1VPTHfiuyEwLo4qQLVTacwYFgNEGrYpCtgO9nmY,3879
|
|
83
|
-
tableauserverclient/server/endpoint/projects_endpoint.py,sha256=
|
|
84
|
-
tableauserverclient/server/endpoint/resource_tagger.py,sha256=
|
|
88
|
+
tableauserverclient/server/endpoint/projects_endpoint.py,sha256=VI-qhBxjg909g_GixzZkdMEQ90p_JZmvRezJvvsHoOs,8703
|
|
89
|
+
tableauserverclient/server/endpoint/resource_tagger.py,sha256=3DEKzY1wegFcHXQg8vyAK9WNMzsUsfhLl3SVWOR-RMQ,6695
|
|
85
90
|
tableauserverclient/server/endpoint/schedules_endpoint.py,sha256=VKlAqTqMtxkvkG2UgZQ6VrBkiAgpjgffRZFzdzV9LtM,6462
|
|
86
91
|
tableauserverclient/server/endpoint/server_info_endpoint.py,sha256=4TtCc7oIp6iEuiZYGC_1NDIBsWetKk7b0rNemoA2VXI,1453
|
|
87
92
|
tableauserverclient/server/endpoint/sites_endpoint.py,sha256=lMeVXxm1k32HZK84u7aTys9hUQekb4PE1hlhKFxaZ8c,6694
|
|
88
93
|
tableauserverclient/server/endpoint/subscriptions_endpoint.py,sha256=mMo9M6DF6tAZIab6UY8f_duETezELl9VXEYs5ocAcGY,3280
|
|
89
|
-
tableauserverclient/server/endpoint/tables_endpoint.py,sha256=
|
|
94
|
+
tableauserverclient/server/endpoint/tables_endpoint.py,sha256=cUAtxc5c2eRFlQ5i02qGjW3I-zQmASVB3nB9VXoCOEc,5838
|
|
90
95
|
tableauserverclient/server/endpoint/tasks_endpoint.py,sha256=HjtSGXBGS8Eriaf5bSWySiqLmKQR_rU4Ao3wGz7Xpd8,4060
|
|
91
|
-
tableauserverclient/server/endpoint/users_endpoint.py,sha256=
|
|
92
|
-
tableauserverclient/server/endpoint/views_endpoint.py,sha256=
|
|
96
|
+
tableauserverclient/server/endpoint/users_endpoint.py,sha256=3USHzwLDPfxERT6t-pyNCQl65LchPa7jPk12T6thizY,8661
|
|
97
|
+
tableauserverclient/server/endpoint/views_endpoint.py,sha256=r9ZVXDtMKvR5h38UcRDQNBl6YXWmIK41vg3pRXxvSeg,10122
|
|
98
|
+
tableauserverclient/server/endpoint/virtual_connections_endpoint.py,sha256=xcE7zn_z2OrsXIvZWpU2XzVoxcNNYRda7VO0d9Q89lg,8449
|
|
93
99
|
tableauserverclient/server/endpoint/webhooks_endpoint.py,sha256=-HsbAuKECNcx5EZkqp097PfGHLCNwPRnxbrdzreTpnM,2835
|
|
94
|
-
tableauserverclient/server/endpoint/workbooks_endpoint.py,sha256=
|
|
95
|
-
tableauserverclient-0.
|
|
96
|
-
tableauserverclient-0.
|
|
97
|
-
tableauserverclient-0.
|
|
98
|
-
tableauserverclient-0.
|
|
99
|
-
tableauserverclient-0.
|
|
100
|
-
tableauserverclient-0.
|
|
100
|
+
tableauserverclient/server/endpoint/workbooks_endpoint.py,sha256=HB3rBE0QCzEDyrZkygvkvfTX7Ro3dlLR3wmJ9jR5uLc,23817
|
|
101
|
+
tableauserverclient-0.33.dist-info/LICENSE,sha256=MMkY7MguOb4L-WCmmqrVcwg2iwSGaz-RfAMFvXRXwsQ,1074
|
|
102
|
+
tableauserverclient-0.33.dist-info/LICENSE.versioneer,sha256=OYaGozOXk7bUNSm1z577iDYpti8a40XIqqR4lyQ47D8,334
|
|
103
|
+
tableauserverclient-0.33.dist-info/METADATA,sha256=X9M9b0bfBW4r4Y-8nZ89ttaR16q8tXeeC6UwWagv1Xg,4327
|
|
104
|
+
tableauserverclient-0.33.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
|
|
105
|
+
tableauserverclient-0.33.dist-info/top_level.txt,sha256=kBnL39G2RlGqxJSsShDBWG4WZ3NFcWJkv1EGiOfZh4Q,20
|
|
106
|
+
tableauserverclient-0.33.dist-info/RECORD,,
|
|
File without changes
|
{tableauserverclient-0.32.dist-info → tableauserverclient-0.33.dist-info}/LICENSE.versioneer
RENAMED
|
File without changes
|
|
File without changes
|