tableauserverclient 0.38__py3-none-any.whl → 0.39__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.
Files changed (117) hide show
  1. tableauserverclient/bin/_version.py → _version.py +3 -3
  2. bin/__init__.py +3 -0
  3. bin/_version.py +21 -0
  4. {tableauserverclient/models → models}/__init__.py +9 -0
  5. models/collection_item.py +52 -0
  6. {tableauserverclient/models → models}/connection_item.py +16 -2
  7. {tableauserverclient/models → models}/custom_view_item.py +8 -0
  8. {tableauserverclient/models → models}/data_freshness_policy_item.py +3 -3
  9. {tableauserverclient/models → models}/datasource_item.py +3 -1
  10. models/extensions_item.py +186 -0
  11. {tableauserverclient/models → models}/favorites_item.py +21 -8
  12. {tableauserverclient/models → models}/flow_item.py +1 -1
  13. {tableauserverclient/models → models}/group_item.py +7 -1
  14. {tableauserverclient/models → models}/groupset_item.py +14 -0
  15. {tableauserverclient/models → models}/interval_item.py +2 -1
  16. models/oidc_item.py +82 -0
  17. {tableauserverclient/models → models}/permissions_item.py +2 -0
  18. {tableauserverclient/models → models}/project_item.py +3 -2
  19. {tableauserverclient/models → models}/property_decorators.py +2 -2
  20. {tableauserverclient/models → models}/reference_item.py +12 -6
  21. {tableauserverclient/models → models}/schedule_item.py +10 -1
  22. {tableauserverclient/models → models}/site_item.py +26 -0
  23. {tableauserverclient/models → models}/tableau_auth.py +13 -6
  24. {tableauserverclient/models → models}/user_item.py +10 -3
  25. {tableauserverclient/models → models}/workbook_item.py +2 -2
  26. {tableauserverclient/server → server}/endpoint/__init__.py +4 -0
  27. {tableauserverclient/server → server}/endpoint/datasources_endpoint.py +152 -22
  28. server/endpoint/extensions_endpoint.py +79 -0
  29. {tableauserverclient/server → server}/endpoint/flow_task_endpoint.py +1 -1
  30. {tableauserverclient/server → server}/endpoint/flows_endpoint.py +5 -4
  31. server/endpoint/oidc_endpoint.py +157 -0
  32. {tableauserverclient/server → server}/endpoint/projects_endpoint.py +12 -0
  33. {tableauserverclient/server → server}/endpoint/schedules_endpoint.py +48 -1
  34. {tableauserverclient/server → server}/endpoint/users_endpoint.py +274 -5
  35. {tableauserverclient/server → server}/endpoint/views_endpoint.py +23 -0
  36. {tableauserverclient/server → server}/endpoint/workbooks_endpoint.py +124 -9
  37. {tableauserverclient/server → server}/request_factory.py +281 -2
  38. {tableauserverclient/server → server}/request_options.py +12 -2
  39. {tableauserverclient/server → server}/server.py +4 -0
  40. {tableauserverclient-0.38.dist-info → tableauserverclient-0.39.dist-info}/METADATA +5 -26
  41. tableauserverclient-0.39.dist-info/RECORD +107 -0
  42. {tableauserverclient-0.38.dist-info → tableauserverclient-0.39.dist-info}/WHEEL +1 -1
  43. tableauserverclient-0.39.dist-info/top_level.txt +4 -0
  44. tableauserverclient/__init__.py +0 -145
  45. tableauserverclient/config.py +0 -27
  46. tableauserverclient/datetime_helpers.py +0 -45
  47. tableauserverclient/exponential_backoff.py +0 -30
  48. tableauserverclient/filesys_helpers.py +0 -63
  49. tableauserverclient/namespace.py +0 -37
  50. tableauserverclient/py.typed +0 -0
  51. tableauserverclient-0.38.dist-info/RECORD +0 -108
  52. tableauserverclient-0.38.dist-info/licenses/LICENSE.versioneer +0 -7
  53. tableauserverclient-0.38.dist-info/top_level.txt +0 -1
  54. {tableauserverclient/helpers → helpers}/__init__.py +0 -0
  55. {tableauserverclient/helpers → helpers}/headers.py +0 -0
  56. {tableauserverclient/helpers → helpers}/logging.py +0 -0
  57. {tableauserverclient/helpers → helpers}/strings.py +0 -0
  58. {tableauserverclient/models → models}/column_item.py +0 -0
  59. {tableauserverclient/models → models}/connection_credentials.py +0 -0
  60. {tableauserverclient/models → models}/data_acceleration_report_item.py +0 -0
  61. {tableauserverclient/models → models}/data_alert_item.py +0 -0
  62. {tableauserverclient/models → models}/database_item.py +0 -0
  63. {tableauserverclient/models → models}/dqw_item.py +0 -0
  64. {tableauserverclient/models → models}/exceptions.py +0 -0
  65. {tableauserverclient/models → models}/extract_item.py +0 -0
  66. {tableauserverclient/models → models}/fileupload_item.py +0 -0
  67. {tableauserverclient/models → models}/flow_run_item.py +0 -0
  68. {tableauserverclient/models → models}/job_item.py +0 -0
  69. {tableauserverclient/models → models}/linked_tasks_item.py +0 -0
  70. {tableauserverclient/models → models}/location_item.py +0 -0
  71. {tableauserverclient/models → models}/metric_item.py +0 -0
  72. {tableauserverclient/models → models}/pagination_item.py +0 -0
  73. {tableauserverclient/models → models}/revision_item.py +0 -0
  74. {tableauserverclient/models → models}/server_info_item.py +0 -0
  75. {tableauserverclient/models → models}/subscription_item.py +0 -0
  76. {tableauserverclient/models → models}/table_item.py +0 -0
  77. {tableauserverclient/models → models}/tableau_types.py +0 -0
  78. {tableauserverclient/models → models}/tag_item.py +0 -0
  79. {tableauserverclient/models → models}/target.py +0 -0
  80. {tableauserverclient/models → models}/task_item.py +0 -0
  81. {tableauserverclient/models → models}/view_item.py +0 -0
  82. {tableauserverclient/models → models}/virtual_connection_item.py +0 -0
  83. {tableauserverclient/models → models}/webhook_item.py +0 -0
  84. {tableauserverclient/server → server}/__init__.py +0 -0
  85. {tableauserverclient/server → server}/endpoint/auth_endpoint.py +0 -0
  86. {tableauserverclient/server → server}/endpoint/custom_views_endpoint.py +0 -0
  87. {tableauserverclient/server → server}/endpoint/data_acceleration_report_endpoint.py +0 -0
  88. {tableauserverclient/server → server}/endpoint/data_alert_endpoint.py +0 -0
  89. {tableauserverclient/server → server}/endpoint/databases_endpoint.py +0 -0
  90. {tableauserverclient/server → server}/endpoint/default_permissions_endpoint.py +0 -0
  91. {tableauserverclient/server → server}/endpoint/dqw_endpoint.py +0 -0
  92. {tableauserverclient/server → server}/endpoint/endpoint.py +0 -0
  93. {tableauserverclient/server → server}/endpoint/exceptions.py +0 -0
  94. {tableauserverclient/server → server}/endpoint/favorites_endpoint.py +0 -0
  95. {tableauserverclient/server → server}/endpoint/fileuploads_endpoint.py +0 -0
  96. {tableauserverclient/server → server}/endpoint/flow_runs_endpoint.py +0 -0
  97. {tableauserverclient/server → server}/endpoint/groups_endpoint.py +0 -0
  98. {tableauserverclient/server → server}/endpoint/groupsets_endpoint.py +0 -0
  99. {tableauserverclient/server → server}/endpoint/jobs_endpoint.py +0 -0
  100. {tableauserverclient/server → server}/endpoint/linked_tasks_endpoint.py +0 -0
  101. {tableauserverclient/server → server}/endpoint/metadata_endpoint.py +0 -0
  102. {tableauserverclient/server → server}/endpoint/metrics_endpoint.py +0 -0
  103. {tableauserverclient/server → server}/endpoint/permissions_endpoint.py +0 -0
  104. {tableauserverclient/server → server}/endpoint/resource_tagger.py +0 -0
  105. {tableauserverclient/server → server}/endpoint/server_info_endpoint.py +0 -0
  106. {tableauserverclient/server → server}/endpoint/sites_endpoint.py +0 -0
  107. {tableauserverclient/server → server}/endpoint/subscriptions_endpoint.py +0 -0
  108. {tableauserverclient/server → server}/endpoint/tables_endpoint.py +0 -0
  109. {tableauserverclient/server → server}/endpoint/tasks_endpoint.py +0 -0
  110. {tableauserverclient/server → server}/endpoint/virtual_connections_endpoint.py +0 -0
  111. {tableauserverclient/server → server}/endpoint/webhooks_endpoint.py +0 -0
  112. {tableauserverclient/server → server}/exceptions.py +0 -0
  113. {tableauserverclient/server → server}/filter.py +0 -0
  114. {tableauserverclient/server → server}/pager.py +0 -0
  115. {tableauserverclient/server → server}/query.py +0 -0
  116. {tableauserverclient/server → server}/sort.py +0 -0
  117. {tableauserverclient-0.38.dist-info → tableauserverclient-0.39.dist-info}/licenses/LICENSE +0 -0
@@ -184,6 +184,9 @@ class DatasourceRequest:
184
184
  project_element = ET.SubElement(datasource_element, "project")
185
185
  project_element.attrib["id"] = datasource_item.project_id
186
186
 
187
+ if datasource_item.description is not None:
188
+ datasource_element.attrib["description"] = datasource_item.description
189
+
187
190
  if connection_credentials is not None and connections is not None:
188
191
  raise RuntimeError("You cannot set both `connections` and `connection_credentials`")
189
192
 
@@ -196,7 +199,7 @@ class DatasourceRequest:
196
199
  _add_connections_element(connections_element, connection)
197
200
  return ET.tostring(xml_request)
198
201
 
199
- def update_req(self, datasource_item):
202
+ def update_req(self, datasource_item: DatasourceItem) -> bytes:
200
203
  xml_request = ET.Element("tsRequest")
201
204
  datasource_element = ET.SubElement(xml_request, "datasource")
202
205
  if datasource_item.name:
@@ -219,6 +222,8 @@ class DatasourceRequest:
219
222
  datasource_element.attrib["certificationNote"] = str(datasource_item.certification_note)
220
223
  if datasource_item.encrypt_extracts is not None:
221
224
  datasource_element.attrib["encryptExtracts"] = str(datasource_item.encrypt_extracts).lower()
225
+ if datasource_item.description is not None:
226
+ datasource_element.attrib["description"] = datasource_item.description
222
227
 
223
228
  return ET.tostring(xml_request)
224
229
 
@@ -244,6 +249,32 @@ class DatasourceRequest:
244
249
  parts = {"request_payload": ("", xml_request, "text/xml")}
245
250
  return _add_multipart(parts)
246
251
 
252
+ @_tsrequest_wrapped
253
+ def update_connections_req(
254
+ self,
255
+ element: ET.Element,
256
+ connection_luids: Iterable[str],
257
+ authentication_type: str,
258
+ username: Optional[str] = None,
259
+ password: Optional[str] = None,
260
+ embed_password: Optional[bool] = None,
261
+ ):
262
+ conn_luids_elem = ET.SubElement(element, "connectionLUIDs")
263
+ for luid in connection_luids:
264
+ ET.SubElement(conn_luids_elem, "connectionLUID").text = luid
265
+
266
+ connection_elem = ET.SubElement(element, "connection")
267
+ connection_elem.set("authenticationType", authentication_type)
268
+
269
+ if username is not None:
270
+ connection_elem.set("userName", username)
271
+
272
+ if password is not None:
273
+ connection_elem.set("password", password)
274
+
275
+ if embed_password is not None:
276
+ connection_elem.set("embedPassword", str(embed_password).lower())
277
+
247
278
 
248
279
  class DQWRequest:
249
280
  def add_req(self, dqw_item):
@@ -486,7 +517,10 @@ class PermissionRequest:
486
517
  for rule in rules:
487
518
  grantee_capabilities_element = ET.SubElement(permissions_element, "granteeCapabilities")
488
519
  grantee_element = ET.SubElement(grantee_capabilities_element, rule.grantee.tag_name)
489
- grantee_element.attrib["id"] = rule.grantee.id
520
+ if rule.grantee.id is not None:
521
+ grantee_element.attrib["id"] = rule.grantee.id
522
+ else:
523
+ raise ValueError("Grantee must have an ID")
490
524
 
491
525
  capabilities_element = ET.SubElement(grantee_capabilities_element, "capabilities")
492
526
  self._add_all_capabilities(capabilities_element, rule.capabilities)
@@ -609,6 +643,16 @@ class ScheduleRequest:
609
643
  def add_flow_req(self, id_: Optional[str], task_type: str = TaskItem.Type.RunFlow) -> bytes:
610
644
  return self._add_to_req(id_, "flow", task_type)
611
645
 
646
+ @_tsrequest_wrapped
647
+ def batch_update_state(self, xml: ET.Element, schedules: Iterable[ScheduleItem | str]) -> None:
648
+ luids = ET.SubElement(xml, "scheduleLuids")
649
+ for schedule in schedules:
650
+ luid = getattr(schedule, "id", schedule)
651
+ if not isinstance(luid, str):
652
+ continue
653
+ luid_tag = ET.SubElement(luids, "scheduleLuid")
654
+ luid_tag.text = luid
655
+
612
656
 
613
657
  class SiteRequest:
614
658
  def update_req(self, site_item: "SiteItem", parent_srv: Optional["Server"] = None):
@@ -715,6 +759,8 @@ class SiteRequest:
715
759
  site_element.attrib["autoSuspendRefreshInactivityWindow"] = str(
716
760
  site_item.auto_suspend_refresh_inactivity_window
717
761
  )
762
+ if site_item.attribute_capture_enabled is not None:
763
+ site_element.attrib["attributeCaptureEnabled"] = str(site_item.attribute_capture_enabled).lower()
718
764
 
719
765
  return ET.tostring(xml_request)
720
766
 
@@ -819,6 +865,8 @@ class SiteRequest:
819
865
  site_element.attrib["autoSuspendRefreshInactivityWindow"] = str(
820
866
  site_item.auto_suspend_refresh_inactivity_window
821
867
  )
868
+ if site_item.attribute_capture_enabled is not None:
869
+ site_element.attrib["attributeCaptureEnabled"] = str(site_item.attribute_capture_enabled).lower()
822
870
 
823
871
  return ET.tostring(xml_request)
824
872
 
@@ -894,6 +942,7 @@ class TagRequest:
894
942
  if item.id is None:
895
943
  raise ValueError(f"Item {item} must have an ID to be tagged.")
896
944
  content_element.attrib["id"] = item.id
945
+ content_element.attrib["contentType"] = item.__class__.__name__.replace("Item", "")
897
946
 
898
947
  return ET.tostring(element)
899
948
 
@@ -936,6 +985,32 @@ class UserRequest:
936
985
  user_element.attrib["idpConfigurationId"] = user_item.idp_configuration_id
937
986
  return ET.tostring(xml_request)
938
987
 
988
+ def import_from_csv_req(self, csv_content: bytes, users: Iterable[UserItem]):
989
+ xml_request = ET.Element("tsRequest")
990
+ for user in users:
991
+ if user.name is None:
992
+ raise ValueError("User name must be populated.")
993
+ user_element = ET.SubElement(xml_request, "user")
994
+ user_element.attrib["name"] = user.name
995
+ if user.auth_setting is not None and user.idp_configuration_id is not None:
996
+ raise ValueError("User cannot have both authSetting and idpConfigurationId.")
997
+ elif user.idp_configuration_id is not None:
998
+ user_element.attrib["idpConfigurationId"] = user.idp_configuration_id
999
+ else:
1000
+ user_element.attrib["authSetting"] = user.auth_setting or "ServerDefault"
1001
+
1002
+ parts = {
1003
+ "tableau_user_import": ("tsc_users_file.csv", csv_content, "file"),
1004
+ "request_payload": ("", ET.tostring(xml_request), "text/xml"),
1005
+ }
1006
+ return _add_multipart(parts)
1007
+
1008
+ def delete_csv_req(self, csv_content: bytes):
1009
+ parts = {
1010
+ "tableau_user_delete": ("tsc_users_file.csv", csv_content, "file"),
1011
+ }
1012
+ return _add_multipart(parts)
1013
+
939
1014
 
940
1015
  class WorkbookRequest:
941
1016
  def _generate_xml(
@@ -1092,6 +1167,32 @@ class WorkbookRequest:
1092
1167
  if (id_ := datasource_item.id) is not None:
1093
1168
  datasource_element.attrib["id"] = id_
1094
1169
 
1170
+ @_tsrequest_wrapped
1171
+ def update_connections_req(
1172
+ self,
1173
+ element: ET.Element,
1174
+ connection_luids: Iterable[str],
1175
+ authentication_type: str,
1176
+ username: Optional[str] = None,
1177
+ password: Optional[str] = None,
1178
+ embed_password: Optional[bool] = None,
1179
+ ):
1180
+ conn_luids_elem = ET.SubElement(element, "connectionLUIDs")
1181
+ for luid in connection_luids:
1182
+ ET.SubElement(conn_luids_elem, "connectionLUID").text = luid
1183
+
1184
+ connection_elem = ET.SubElement(element, "connection")
1185
+ connection_elem.set("authenticationType", authentication_type)
1186
+
1187
+ if username is not None:
1188
+ connection_elem.set("userName", username)
1189
+
1190
+ if password is not None:
1191
+ connection_elem.set("password", password)
1192
+
1193
+ if embed_password is not None:
1194
+ connection_elem.set("embedPassword", str(embed_password).lower())
1195
+
1095
1196
 
1096
1197
  class Connection:
1097
1198
  @_tsrequest_wrapped
@@ -1110,6 +1211,8 @@ class Connection:
1110
1211
  connection_element.attrib["userName"] = connection_item.username
1111
1212
  if connection_item.password is not None:
1112
1213
  connection_element.attrib["password"] = connection_item.password
1214
+ if connection_item.auth_type is not None:
1215
+ connection_element.attrib["authenticationType"] = connection_item.auth_type
1113
1216
  if connection_item.embed_password is not None:
1114
1217
  connection_element.attrib["embedPassword"] = str(connection_item.embed_password).lower()
1115
1218
  if connection_item.query_tagging is not None:
@@ -1446,6 +1549,180 @@ class VirtualConnectionRequest:
1446
1549
  return ET.tostring(xml_request)
1447
1550
 
1448
1551
 
1552
+ class OIDCRequest:
1553
+ @_tsrequest_wrapped
1554
+ def create_req(self, xml_request: ET.Element, oidc_item: SiteOIDCConfiguration) -> bytes:
1555
+ oidc_element = ET.SubElement(xml_request, "siteOIDCConfiguration")
1556
+
1557
+ # Check required attributes first
1558
+
1559
+ if oidc_item.idp_configuration_name is None:
1560
+ raise ValueError(f"OIDC Item missing idp_configuration_name: {oidc_item}")
1561
+ if oidc_item.client_id is None:
1562
+ raise ValueError(f"OIDC Item missing client_id: {oidc_item}")
1563
+ if oidc_item.client_secret is None:
1564
+ raise ValueError(f"OIDC Item missing client_secret: {oidc_item}")
1565
+ if oidc_item.authorization_endpoint is None:
1566
+ raise ValueError(f"OIDC Item missing authorization_endpoint: {oidc_item}")
1567
+ if oidc_item.token_endpoint is None:
1568
+ raise ValueError(f"OIDC Item missing token_endpoint: {oidc_item}")
1569
+ if oidc_item.userinfo_endpoint is None:
1570
+ raise ValueError(f"OIDC Item missing userinfo_endpoint: {oidc_item}")
1571
+ if not isinstance(oidc_item.enabled, bool):
1572
+ raise ValueError(f"OIDC Item missing enabled: {oidc_item}")
1573
+ if oidc_item.jwks_uri is None:
1574
+ raise ValueError(f"OIDC Item missing jwks_uri: {oidc_item}")
1575
+
1576
+ oidc_element.attrib["name"] = oidc_item.idp_configuration_name
1577
+ oidc_element.attrib["clientId"] = oidc_item.client_id
1578
+ oidc_element.attrib["clientSecret"] = oidc_item.client_secret
1579
+ oidc_element.attrib["authorizationEndpoint"] = oidc_item.authorization_endpoint
1580
+ oidc_element.attrib["tokenEndpoint"] = oidc_item.token_endpoint
1581
+ oidc_element.attrib["userInfoEndpoint"] = oidc_item.userinfo_endpoint
1582
+ oidc_element.attrib["enabled"] = str(oidc_item.enabled).lower()
1583
+ oidc_element.attrib["jwksUri"] = oidc_item.jwks_uri
1584
+
1585
+ if oidc_item.allow_embedded_authentication is not None:
1586
+ oidc_element.attrib["allowEmbeddedAuthentication"] = str(oidc_item.allow_embedded_authentication).lower()
1587
+ if oidc_item.custom_scope is not None:
1588
+ oidc_element.attrib["customScope"] = oidc_item.custom_scope
1589
+ if oidc_item.prompt is not None:
1590
+ oidc_element.attrib["prompt"] = oidc_item.prompt
1591
+ if oidc_item.client_authentication is not None:
1592
+ oidc_element.attrib["clientAuthentication"] = oidc_item.client_authentication
1593
+ if oidc_item.essential_acr_values is not None:
1594
+ oidc_element.attrib["essentialAcrValues"] = oidc_item.essential_acr_values
1595
+ if oidc_item.voluntary_acr_values is not None:
1596
+ oidc_element.attrib["voluntaryAcrValues"] = oidc_item.voluntary_acr_values
1597
+ if oidc_item.email_mapping is not None:
1598
+ oidc_element.attrib["emailMapping"] = oidc_item.email_mapping
1599
+ if oidc_item.first_name_mapping is not None:
1600
+ oidc_element.attrib["firstNameMapping"] = oidc_item.first_name_mapping
1601
+ if oidc_item.last_name_mapping is not None:
1602
+ oidc_element.attrib["lastNameMapping"] = oidc_item.last_name_mapping
1603
+ if oidc_item.full_name_mapping is not None:
1604
+ oidc_element.attrib["fullNameMapping"] = oidc_item.full_name_mapping
1605
+ if oidc_item.use_full_name is not None:
1606
+ oidc_element.attrib["useFullName"] = str(oidc_item.use_full_name).lower()
1607
+
1608
+ return ET.tostring(xml_request)
1609
+
1610
+ @_tsrequest_wrapped
1611
+ def update_req(self, xml_request: ET.Element, oidc_item: SiteOIDCConfiguration) -> bytes:
1612
+ oidc_element = ET.SubElement(xml_request, "siteOIDCConfiguration")
1613
+
1614
+ # Check required attributes first
1615
+
1616
+ if oidc_item.idp_configuration_name is None:
1617
+ raise ValueError(f"OIDC Item missing idp_configuration_name: {oidc_item}")
1618
+ if oidc_item.client_id is None:
1619
+ raise ValueError(f"OIDC Item missing client_id: {oidc_item}")
1620
+ if oidc_item.client_secret is None:
1621
+ raise ValueError(f"OIDC Item missing client_secret: {oidc_item}")
1622
+ if oidc_item.authorization_endpoint is None:
1623
+ raise ValueError(f"OIDC Item missing authorization_endpoint: {oidc_item}")
1624
+ if oidc_item.token_endpoint is None:
1625
+ raise ValueError(f"OIDC Item missing token_endpoint: {oidc_item}")
1626
+ if oidc_item.userinfo_endpoint is None:
1627
+ raise ValueError(f"OIDC Item missing userinfo_endpoint: {oidc_item}")
1628
+ if not isinstance(oidc_item.enabled, bool):
1629
+ raise ValueError(f"OIDC Item missing enabled: {oidc_item}")
1630
+ if oidc_item.jwks_uri is None:
1631
+ raise ValueError(f"OIDC Item missing jwks_uri: {oidc_item}")
1632
+
1633
+ oidc_element.attrib["name"] = oidc_item.idp_configuration_name
1634
+ oidc_element.attrib["clientId"] = oidc_item.client_id
1635
+ oidc_element.attrib["clientSecret"] = oidc_item.client_secret
1636
+ oidc_element.attrib["authorizationEndpoint"] = oidc_item.authorization_endpoint
1637
+ oidc_element.attrib["tokenEndpoint"] = oidc_item.token_endpoint
1638
+ oidc_element.attrib["userInfoEndpoint"] = oidc_item.userinfo_endpoint
1639
+ oidc_element.attrib["enabled"] = str(oidc_item.enabled).lower()
1640
+ oidc_element.attrib["jwksUri"] = oidc_item.jwks_uri
1641
+
1642
+ if oidc_item.allow_embedded_authentication is not None:
1643
+ oidc_element.attrib["allowEmbeddedAuthentication"] = str(oidc_item.allow_embedded_authentication).lower()
1644
+ if oidc_item.custom_scope is not None:
1645
+ oidc_element.attrib["customScope"] = oidc_item.custom_scope
1646
+ if oidc_item.prompt is not None:
1647
+ oidc_element.attrib["prompt"] = oidc_item.prompt
1648
+ if oidc_item.client_authentication is not None:
1649
+ oidc_element.attrib["clientAuthentication"] = oidc_item.client_authentication
1650
+ if oidc_item.essential_acr_values is not None:
1651
+ oidc_element.attrib["essentialAcrValues"] = oidc_item.essential_acr_values
1652
+ if oidc_item.voluntary_acr_values is not None:
1653
+ oidc_element.attrib["voluntaryAcrValues"] = oidc_item.voluntary_acr_values
1654
+ if oidc_item.email_mapping is not None:
1655
+ oidc_element.attrib["emailMapping"] = oidc_item.email_mapping
1656
+ if oidc_item.first_name_mapping is not None:
1657
+ oidc_element.attrib["firstNameMapping"] = oidc_item.first_name_mapping
1658
+ if oidc_item.last_name_mapping is not None:
1659
+ oidc_element.attrib["lastNameMapping"] = oidc_item.last_name_mapping
1660
+ if oidc_item.full_name_mapping is not None:
1661
+ oidc_element.attrib["fullNameMapping"] = oidc_item.full_name_mapping
1662
+ if oidc_item.use_full_name is not None:
1663
+ oidc_element.attrib["useFullName"] = str(oidc_item.use_full_name).lower()
1664
+
1665
+ return ET.tostring(xml_request)
1666
+
1667
+
1668
+ class ExtensionsRequest:
1669
+ @_tsrequest_wrapped
1670
+ def update_server_extensions(self, xml_request: ET.Element, extensions_server: "ExtensionsServer") -> None:
1671
+ extensions_element = ET.SubElement(xml_request, "extensionsServerSettings")
1672
+ if not isinstance(extensions_server.enabled, bool):
1673
+ raise ValueError(f"Extensions Server missing enabled: {extensions_server}")
1674
+ enabled_element = ET.SubElement(extensions_element, "extensionsGloballyEnabled")
1675
+ enabled_element.text = str(extensions_server.enabled).lower()
1676
+
1677
+ if extensions_server.block_list is None:
1678
+ return
1679
+ for blocked in extensions_server.block_list:
1680
+ blocked_element = ET.SubElement(extensions_element, "blockList")
1681
+ blocked_element.text = blocked
1682
+ return
1683
+
1684
+ @_tsrequest_wrapped
1685
+ def update_site_extensions(self, xml_request: ET.Element, extensions_site_settings: ExtensionsSiteSettings) -> None:
1686
+ ext_element = ET.SubElement(xml_request, "extensionsSiteSettings")
1687
+ if not isinstance(extensions_site_settings.enabled, bool):
1688
+ raise ValueError(f"Extensions Site Settings missing enabled: {extensions_site_settings}")
1689
+ enabled_element = ET.SubElement(ext_element, "extensionsEnabled")
1690
+ enabled_element.text = str(extensions_site_settings.enabled).lower()
1691
+ if not isinstance(extensions_site_settings.use_default_setting, bool):
1692
+ raise ValueError(
1693
+ f"Extensions Site Settings missing use_default_setting: {extensions_site_settings.use_default_setting}"
1694
+ )
1695
+ default_element = ET.SubElement(ext_element, "useDefaultSetting")
1696
+ default_element.text = str(extensions_site_settings.use_default_setting).lower()
1697
+ if extensions_site_settings.allow_trusted is not None:
1698
+ allow_trusted_element = ET.SubElement(ext_element, "allowTrusted")
1699
+ allow_trusted_element.text = str(extensions_site_settings.allow_trusted).lower()
1700
+ if extensions_site_settings.include_sandboxed is not None:
1701
+ include_sandboxed_element = ET.SubElement(ext_element, "includeSandboxed")
1702
+ include_sandboxed_element.text = str(extensions_site_settings.include_sandboxed).lower()
1703
+ if extensions_site_settings.include_tableau_built is not None:
1704
+ include_tableau_built_element = ET.SubElement(ext_element, "includeTableauBuilt")
1705
+ include_tableau_built_element.text = str(extensions_site_settings.include_tableau_built).lower()
1706
+ if extensions_site_settings.include_partner_built is not None:
1707
+ include_partner_built_element = ET.SubElement(ext_element, "includePartnerBuilt")
1708
+ include_partner_built_element.text = str(extensions_site_settings.include_partner_built).lower()
1709
+
1710
+ if extensions_site_settings.safe_list is None:
1711
+ return
1712
+
1713
+ safe_element = ET.SubElement(ext_element, "safeList")
1714
+ for safe in extensions_site_settings.safe_list:
1715
+ if safe.url is not None:
1716
+ url_element = ET.SubElement(safe_element, "url")
1717
+ url_element.text = safe.url
1718
+ if safe.full_data_allowed is not None:
1719
+ full_data_element = ET.SubElement(safe_element, "fullDataAllowed")
1720
+ full_data_element.text = str(safe.full_data_allowed).lower()
1721
+ if safe.prompt_needed is not None:
1722
+ prompt_element = ET.SubElement(safe_element, "promptNeeded")
1723
+ prompt_element.text = str(safe.prompt_needed).lower()
1724
+
1725
+
1449
1726
  class RequestFactory:
1450
1727
  Auth = AuthRequest()
1451
1728
  Connection = Connection()
@@ -1456,6 +1733,7 @@ class RequestFactory:
1456
1733
  Database = DatabaseRequest()
1457
1734
  DQW = DQWRequest()
1458
1735
  Empty = EmptyRequest()
1736
+ Extensions = ExtensionsRequest()
1459
1737
  Favorite = FavoriteRequest()
1460
1738
  Fileupload = FileuploadRequest()
1461
1739
  Flow = FlowRequest()
@@ -1463,6 +1741,7 @@ class RequestFactory:
1463
1741
  Group = GroupRequest()
1464
1742
  GroupSet = GroupSetRequest()
1465
1743
  Metric = MetricRequest()
1744
+ OIDC = OIDCRequest()
1466
1745
  Permission = PermissionRequest()
1467
1746
  Project = ProjectRequest()
1468
1747
  Schedule = ScheduleRequest()
@@ -96,7 +96,10 @@ class RequestOptions(RequestOptionsBase):
96
96
  if self.pagesize:
97
97
  params["pageSize"] = self.pagesize
98
98
  if self.fields:
99
- params["fields"] = ",".join(self.fields)
99
+ if "_all_" in self.fields:
100
+ params["fields"] = "_all_"
101
+ else:
102
+ params["fields"] = ",".join(sorted(self.fields))
100
103
  return params
101
104
 
102
105
  def page_size(self, page_size):
@@ -384,7 +387,14 @@ class _DataExportOptions(RequestOptionsBase):
384
387
  Self
385
388
  The current object
386
389
  """
387
- self.view_parameters.append((name, value))
390
+ prefix = "vf_Parameters."
391
+ if name.startswith(prefix):
392
+ proper_name = name
393
+ elif name.startswith("Parameters."):
394
+ proper_name = f"vf_{name}"
395
+ else:
396
+ proper_name = f"{prefix}{name}"
397
+ self.view_parameters.append((proper_name, value))
388
398
  return self
389
399
 
390
400
  def _append_view_filters(self, params) -> None:
@@ -38,6 +38,8 @@ from tableauserverclient.server.endpoint import (
38
38
  GroupSets,
39
39
  Tags,
40
40
  VirtualConnections,
41
+ OIDC,
42
+ Extensions,
41
43
  )
42
44
  from tableauserverclient.server.exceptions import (
43
45
  ServerInfoEndpointNotFoundError,
@@ -183,6 +185,8 @@ class Server:
183
185
  self.group_sets = GroupSets(self)
184
186
  self.tags = Tags(self)
185
187
  self.virtual_connections = VirtualConnections(self)
188
+ self.oidc = OIDC(self)
189
+ self.extensions = Extensions(self)
186
190
 
187
191
  self._session = self._session_factory()
188
192
  self._http_options = dict() # must set this before making a server call
@@ -1,30 +1,8 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tableauserverclient
3
- Version: 0.38
3
+ Version: 0.39
4
4
  Summary: A Python module for working with the Tableau Server REST API.
5
5
  Author-email: Tableau <github@tableau.com>
6
- License: The MIT License (MIT)
7
-
8
- Copyright (c) 2022 Tableau
9
-
10
- Permission is hereby granted, free of charge, to any person obtaining a copy
11
- of this software and associated documentation files (the "Software"), to deal
12
- in the Software without restriction, including without limitation the rights
13
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
- copies of the Software, and to permit persons to whom the Software is
15
- furnished to do so, subject to the following conditions:
16
-
17
- The above copyright notice and this permission notice shall be included in all
18
- copies or substantial portions of the Software.
19
-
20
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
- SOFTWARE.
27
-
28
6
  Project-URL: repository, https://github.com/tableau/server-client-python
29
7
  Classifier: Programming Language :: Python
30
8
  Classifier: Programming Language :: Python :: 3
@@ -36,20 +14,21 @@ Classifier: Programming Language :: Python :: 3.13
36
14
  Requires-Python: >=3.9
37
15
  Description-Content-Type: text/markdown
38
16
  License-File: LICENSE
39
- License-File: LICENSE.versioneer
40
17
  Requires-Dist: defusedxml>=0.7.1
41
18
  Requires-Dist: packaging>=23.1
42
19
  Requires-Dist: requests>=2.32
43
- Requires-Dist: urllib3<3,>=2.2.2
20
+ Requires-Dist: urllib3<3,>=2.6.0
44
21
  Requires-Dist: typing_extensions>=4.0
45
22
  Provides-Extra: test
46
- Requires-Dist: black==24.8; extra == "test"
23
+ Requires-Dist: black==24.10; extra == "test"
47
24
  Requires-Dist: build; extra == "test"
48
25
  Requires-Dist: mypy==1.4; extra == "test"
49
26
  Requires-Dist: pytest>=7.0; extra == "test"
50
27
  Requires-Dist: pytest-cov; extra == "test"
51
28
  Requires-Dist: pytest-subtests; extra == "test"
29
+ Requires-Dist: pytest-xdist; extra == "test"
52
30
  Requires-Dist: requests-mock<2.0,>=1.0; extra == "test"
31
+ Requires-Dist: types-requests>=2.32.4.20250913; extra == "test"
53
32
  Dynamic: license-file
54
33
 
55
34
  # Tableau Server Client (Python)
@@ -0,0 +1,107 @@
1
+ _version.py,sha256=Gj76mmCMMylBUJ_rBL4WMy9bM-2DediAdkn9393A6Tc,496
2
+ bin/__init__.py,sha256=T8WHy9zTlF9XZWoqqMbrxJ39Tw4YHo4x7zq9iSQRioQ,119
3
+ bin/_version.py,sha256=Gj76mmCMMylBUJ_rBL4WMy9bM-2DediAdkn9393A6Tc,496
4
+ helpers/__init__.py,sha256=llpqF9zV5dsP5hQt8dyop33Op5OzGmxW0BZibaSlCcM,23
5
+ helpers/headers.py,sha256=Pg-ZWSgV2Yp813BV1Tzo8F2Hn4P01zscla2RRM4yqNk,411
6
+ helpers/logging.py,sha256=5q_oR3wERHVXFXY6XDnLYML5-HdAPJTmqhH9IZg4VfY,113
7
+ helpers/strings.py,sha256=7MvaS9haJ5hpdv4NPQ11gRj94zIgbDmujFPD_GnZPJI,2013
8
+ models/__init__.py,sha256=m_hsDtY9aQwtd1rtg34QqmBVBF1wGh3SEArFjKMP1-8,4679
9
+ models/collection_item.py,sha256=nZISWKtjsuAHSBrw9_h1Xco0zHNf1x5uQ0UAH2MWxaQ,2162
10
+ models/column_item.py,sha256=yUFzXNcnUPVo2imrhEBS4fMVAR5j2ZzksOk5t9XYW5s,1964
11
+ models/connection_credentials.py,sha256=CQ8FkkHW9MeTw8uArNhrU5mowtryWUddgEgEliqh3ys,2066
12
+ models/connection_item.py,sha256=QO-20N7df-5V1rCnaZCQ6bxLRncctWvprq1aXSOF7YE,6553
13
+ models/custom_view_item.py,sha256=oIdYhyWLhJZUaSsp9QAAAka9AP7kO8LOaN97vPw95Qw,7967
14
+ models/data_acceleration_report_item.py,sha256=HFZROetfOWh-hMS48xBEHqYOViINHZR-EpcrP45_8AI,3386
15
+ models/data_alert_item.py,sha256=VZtRR-kqojq-mkrTgvay4WkPawj3-4jbSc0wBijmJhk,6444
16
+ models/data_freshness_policy_item.py,sha256=k_EfTuf9Av6kDEapmqiLbkzT8W4yEYS6V3EY0CRXPbM,7648
17
+ models/database_item.py,sha256=lWxmmMpPeVxzizVAsVkc6Ps2I-j-0KJAJZto8qShrYU,8223
18
+ models/datasource_item.py,sha256=ITVzWLHdY2xLhP1UCWJqE9j5ZijomxT83p5B_WE78I4,19735
19
+ models/dqw_item.py,sha256=87oTc7icrQst_DSaTqoVR965YEckg5dk6osa51BrCAk,3710
20
+ models/exceptions.py,sha256=pQu5DS4jNMT9A0wEBWv2vANAQU1vgNpFatVr8sGE4zk,105
21
+ models/extensions_item.py,sha256=nJj5Xl_B1j5KK6TQ8-g8tBaBH5tkCsR2Y0GTnuOcxWQ,6684
22
+ models/extract_item.py,sha256=2qDyNrAanbw1gK6qE2L7RwQFsIg_59unUx8rbLWrTmg,2691
23
+ models/favorites_item.py,sha256=IvImwOW8csz14HdrTVSDZ6mCubyuYjTLsI9yS3nD2jE,3947
24
+ models/fileupload_item.py,sha256=N5M0jtlFj_PFh3jlp2AbcYOwCwdnBCk_L64xe3Z4ves,742
25
+ models/flow_item.py,sha256=sFAgm-RSJOBaq2CTZvL9F0wD3MiO0r7tBXfqVR7JDic,8674
26
+ models/flow_run_item.py,sha256=nf_b6KRwNevwZRsPoMh8dLzdONUMWY2wipWEMdY9SN4,3113
27
+ models/group_item.py,sha256=7i-b4GvAC03GQtR8BweTDj5xcxEDvoer5EXuygvIYVU,5532
28
+ models/groupset_item.py,sha256=sNaXHbFLxC1sLiJgA_Dbm_d2nny2sRVN383Dltvy-kQ,2339
29
+ models/interval_item.py,sha256=q-SK-Coo3WhoLsNbzkC4K3qYCMfcNnrRzAmKmdIKuIY,11016
30
+ models/job_item.py,sha256=Q7tTKXEiW-5VJsLmnAq6auP0jvmbbImmqw_nx1kiXtM,11512
31
+ models/linked_tasks_item.py,sha256=TYkNvmJfKlZ30OST8w9GUobboFAH5ftFKjXdWWAtR24,3806
32
+ models/location_item.py,sha256=8pVxiSoySTAQOF9QDe0KiHMUp0aiFG-sZ2cB1u8oAEg,1287
33
+ models/metric_item.py,sha256=D3atzbr3jtQUsVsqYHfz-v3yRP3qruRN5jRsv_-yRQ0,5378
34
+ models/oidc_item.py,sha256=hKqX8QiIUtd6keXKT9l9LzhIMkaO2QkvXkp2VxzhkHQ,3753
35
+ models/pagination_item.py,sha256=55Ap_9pJxq8plWQO1Js3Jp6KFidN3TQsL5LM2-yZGDo,1424
36
+ models/permissions_item.py,sha256=Av_z2P8IbxH-FXWMhOPGZapPR6qQRrYfqo30nZjMBrM,6245
37
+ models/project_item.py,sha256=MFUJ9vDbsTdZXmWtmeWKitffZ7lFfP2eOZY-HSvSIbM,11729
38
+ models/property_decorators.py,sha256=Xp08wlfbHImLEgb9TrdbdFTlAGCO3RR68Sw5qvnBDJ4,4632
39
+ models/reference_item.py,sha256=8cFg61-Y2NQsDE5IAHGSYU5p3unVB2nHclOq8e8EFFs,940
40
+ models/revision_item.py,sha256=5ghmnwhUcCOWwZdApzgV_uM3sqdoG_gtsJwUQwfKITo,2773
41
+ models/schedule_item.py,sha256=553k5g1gbLiNs4_4NLbDhTKDgU4lqXfK6fBh35-tSxY,13770
42
+ models/server_info_item.py,sha256=55wTG_31o-WwqgBrbwpgMpq_by10iM6BXpmdAZ3TO90,2631
43
+ models/site_item.py,sha256=Wq5Ry_14RUgJEXDAcs87SFAaRsvVlUqQYbQ6CWe1l30,47296
44
+ models/subscription_item.py,sha256=ujaQQIo_ln3pnm0Th2IdcGCp_cl6WxvEMPgeZbwZtFc,4724
45
+ models/table_item.py,sha256=4CZ2R0asNz8iINn3FKKQzjpwt-5lBAvfm0fHKmz5gcw,4752
46
+ models/tableau_auth.py,sha256=F1AOyKCaxwS4q_1HbNC8nw2KBaYNexXescxZdHhNkjw,8394
47
+ models/tableau_types.py,sha256=bukzI490GWpebGv9ZiCuSqioqIZm9ao9Yr2GGrmM8_A,1420
48
+ models/tag_item.py,sha256=K2EVEy1EDdr0yLr4wBvGr-p9gIAFVsOCv80b-AFPFLk,588
49
+ models/target.py,sha256=dVc1SHwo9ZASR8250MhAPODXX_G5UqA4BnK8hykRE6E,263
50
+ models/task_item.py,sha256=l4t4COw2LfdlYmJpzUSgwGven_NSZj2r3PUJZkqvCus,4555
51
+ models/user_item.py,sha256=Nynycb3lM2q909P8bML6xOncr4P1yBhWO17lE_Nh9P8,19814
52
+ models/view_item.py,sha256=-JxiwRFqBo7DS3dvwk4rxRhc25WH-Pgf8rBaLyFQOzE,12451
53
+ models/virtual_connection_item.py,sha256=TvX7MId7WSg4IZE41XAMl1l3Ibu8kTUR1xr26Cqtyeo,3357
54
+ models/webhook_item.py,sha256=r37fHY3_uhDhxupHfMSvB4I2aUjy3qQ2FOLQjAcNUUk,3994
55
+ models/workbook_item.py,sha256=myU8Tesc5eGwmYEICQdk3aXtxERkHdC8FEk1zwO65Y4,22404
56
+ server/__init__.py,sha256=77E-3LseLd9gHeRgKPnpZTNMQySgYiwst33AsReol-k,1940
57
+ server/exceptions.py,sha256=l-O4lcoEeXJC7fLWUanIcZM_Mf8m54uK3NQuKNj3RCg,183
58
+ server/filter.py,sha256=Z7O6A175bBSmcponLs0Enh5R5Gp2puVRGfOMk-V395w,1096
59
+ server/pager.py,sha256=IESvCba7WZO3O9VBcKlJ6ricVDgro0gKuUQyJnOCUws,3497
60
+ server/query.py,sha256=dY_y20DOBOFwydIpLcWLK39s1lVmDPxhX5x6hVxeoL0,10529
61
+ server/request_factory.py,sha256=2A6mFp-eLi7wd18I1QySULvCx1B78EHyNu59Oj2dzsM,87792
62
+ server/request_options.py,sha256=xVMZYO_dXdDHWi4bYalA8w-n55z-qSuSNGRGwwEFUCU,20251
63
+ server/server.py,sha256=YC7rmMdw7asDMsvq2M5FGujl3FE2qP35M5DOwnNwHZ4,13463
64
+ server/sort.py,sha256=wjnlt7rlmLvQjM_XpgD8N8Hlg0zVvLOV7k_dAs1DmHY,628
65
+ server/endpoint/__init__.py,sha256=kHDGHsGU0QgJVBzMzerfR8vQ476ksC0QFQJfMDvQ_Vk,3277
66
+ server/endpoint/auth_endpoint.py,sha256=8N3_OUSwYm4KCvwDJHGmH9i2OqzH70PLP0-rT-sKYVo,7177
67
+ server/endpoint/custom_views_endpoint.py,sha256=se-CZ9BF8Cf_quT_3BbrO9lwK7E8hHbCoMYq-2IZMM8,14515
68
+ server/endpoint/data_acceleration_report_endpoint.py,sha256=he-MVqCvAQo8--icEKFoIV2KUP6Z1s_PJ2uZ8Xpj2f8,1130
69
+ server/endpoint/data_alert_endpoint.py,sha256=ZNotgG3hBpR7fo8eDTXx_gSppF2n25GQ3udwF3MKFLk,5203
70
+ server/endpoint/databases_endpoint.py,sha256=vojSCB6DQ665Z0X7h5TQg5wflU_WUtd4pgcjsda7JdU,8689
71
+ server/endpoint/datasources_endpoint.py,sha256=CQ6erQgiWIKgyfAPDtwFquXNy6MxdSIcjjhsbRrZN6I,44921
72
+ server/endpoint/default_permissions_endpoint.py,sha256=bZlhDqu6jFyC4vbrdC3Nn1cWRJWRz0mhxco9hRUouJA,4327
73
+ server/endpoint/dqw_endpoint.py,sha256=bfgA7sRGQajR67xcRS9mIF7yKlJmjjFyN-hBxwZ5wkU,2626
74
+ server/endpoint/endpoint.py,sha256=035rsaaUoQP0oYtaRhtIMHs9bwMeFCt2u-gn5asOK7o,15309
75
+ server/endpoint/exceptions.py,sha256=ifkRatvvqG5awY73BzwALlby3dYYKr_8leUOmpeZS0Y,2919
76
+ server/endpoint/extensions_endpoint.py,sha256=sInHr4sDMoXC7X-eHyOmP4bJfJbUypalfsUEKHK_F7Y,2992
77
+ server/endpoint/favorites_endpoint.py,sha256=ZMui0KQCSGRBlUrem519Y5_gBpngN7wtDWo_EvEUMEk,6340
78
+ server/endpoint/fileuploads_endpoint.py,sha256=e3qIw6lJJG4Y8RHG26psMjjETovpfrBzmFjeYeJll8s,2410
79
+ server/endpoint/flow_runs_endpoint.py,sha256=HIVuTi4pXIqog16K_3Zzu1LC96TR_pZlAjxRKoJrJ_g,4957
80
+ server/endpoint/flow_task_endpoint.py,sha256=z9qrWw9hrWXPHwRT9j0vx9PeW_kL_yphB5h9-inLj6M,1075
81
+ server/endpoint/flows_endpoint.py,sha256=GLODBEg31O-mZeqLV6kjaPGg0bLP93_kl6ok2GF_k4A,23738
82
+ server/endpoint/groups_endpoint.py,sha256=5ZhKJeKT3GoM2olqJYJggdiVYQ9BdcEJCIqkx-tZqxo,18745
83
+ server/endpoint/groupsets_endpoint.py,sha256=Kcrrd0NbduwIhAtGkG-EMf38qcCM74EnCybAs24TFnM,5577
84
+ server/endpoint/jobs_endpoint.py,sha256=rhR8tD89U5ha-g5QhLlGXurTF77mLQREnd7k208EHxA,10387
85
+ server/endpoint/linked_tasks_endpoint.py,sha256=tMZqVPWPZvYawaXLJGVV9scmWPu1rdCxz-eWZv1WbPk,2262
86
+ server/endpoint/metadata_endpoint.py,sha256=sg0Yehj2f0wlrJMkVjzNdNxNEhSeNbZIkio3eQamOVk,5228
87
+ server/endpoint/metrics_endpoint.py,sha256=p9F_tbUela1sb3i9n67Tr9zsPRmsjSAigC6EqLwZHqE,3175
88
+ server/endpoint/oidc_endpoint.py,sha256=OMOpOOcPO8C1z6FFRHf6CEVgJqWgaETRSWPiQdYg4wA,5969
89
+ server/endpoint/permissions_endpoint.py,sha256=tXX_KSanbxUeR-L4UdI_jphko8dD_fZsXVhQayQL3JA,3719
90
+ server/endpoint/projects_endpoint.py,sha256=cIeoCGUCiUl_MtpHDycI21n9DIjGfSvFeyGW1iDduwo,31114
91
+ server/endpoint/resource_tagger.py,sha256=eKekflXzLjx_zDOLgYkTIusRO8vsFus1LvLIf0LOwtQ,6661
92
+ server/endpoint/schedules_endpoint.py,sha256=C4evSP4P6_7cxTlk71IaswIxba7Bo2I5eVM-W5cfyGU,12716
93
+ server/endpoint/server_info_endpoint.py,sha256=9UcYP3td22S_Kwabu-RWc-Pn3lFrIERVlzVpl4ErP_I,2649
94
+ server/endpoint/sites_endpoint.py,sha256=Fh8ppL00IVI1YpXyOXCCc5fIc_r_TC1o8GCgYD_gOV4,14778
95
+ server/endpoint/subscriptions_endpoint.py,sha256=21oZ6Q14AL8p2ZHyfREpbnPU6Vj4Xh97o1K9hmKRJ-I,3187
96
+ server/endpoint/tables_endpoint.py,sha256=PcNqk66aJ_rsFSHOJ1FCB_G5GlvGFIzr66G5aO2aIRo,9742
97
+ server/endpoint/tasks_endpoint.py,sha256=5VHGe2NSgr40BKPPOm9nVrdZGrG3Sf0ri_CNqsv0CpQ,6304
98
+ server/endpoint/users_endpoint.py,sha256=How6_592NotSDF__pRSQ_IMkKWX-jjRKIHTVCsTXfgo,30054
99
+ server/endpoint/views_endpoint.py,sha256=p4rSEPS3Octgm9W7b1QHSaxVJW4F5KJHoYXTymYMo-o,18639
100
+ server/endpoint/virtual_connections_endpoint.py,sha256=K5R86aIm4hZeYw3OUOlKv-zTmsWa3np1iuV_h5iPvt0,8458
101
+ server/endpoint/webhooks_endpoint.py,sha256=nmEjKdbntwBg-0XAP2TluOv2v8usqxXg7sO8ogS5rDI,4923
102
+ server/endpoint/workbooks_endpoint.py,sha256=tN5AybuR8lZxwM6OFtJLJ0Cryo2d8thWHUONCT4OK7k,47116
103
+ tableauserverclient-0.39.dist-info/licenses/LICENSE,sha256=MMkY7MguOb4L-WCmmqrVcwg2iwSGaz-RfAMFvXRXwsQ,1074
104
+ tableauserverclient-0.39.dist-info/METADATA,sha256=nddyyUHFsllYnxKmsXLyE8_9ot7Cx3Cp36KPbejGbVc,3176
105
+ tableauserverclient-0.39.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
106
+ tableauserverclient-0.39.dist-info/top_level.txt,sha256=mYhy_-A6qRwugiu8LrbB_k66cJASefpXAZrD1u_5CZk,26
107
+ tableauserverclient-0.39.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.7.1)
2
+ Generator: setuptools (80.10.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -0,0 +1,4 @@
1
+ bin
2
+ helpers
3
+ models
4
+ server