tableauserverclient 0.33__py3-none-any.whl → 0.35__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 (94) hide show
  1. tableauserverclient/__init__.py +33 -23
  2. tableauserverclient/{_version.py → bin/_version.py} +3 -3
  3. tableauserverclient/config.py +5 -3
  4. tableauserverclient/models/column_item.py +1 -1
  5. tableauserverclient/models/connection_credentials.py +18 -2
  6. tableauserverclient/models/connection_item.py +44 -6
  7. tableauserverclient/models/custom_view_item.py +78 -11
  8. tableauserverclient/models/data_acceleration_report_item.py +2 -2
  9. tableauserverclient/models/data_alert_item.py +5 -5
  10. tableauserverclient/models/data_freshness_policy_item.py +6 -6
  11. tableauserverclient/models/database_item.py +3 -3
  12. tableauserverclient/models/datasource_item.py +10 -10
  13. tableauserverclient/models/dqw_item.py +1 -1
  14. tableauserverclient/models/favorites_item.py +5 -6
  15. tableauserverclient/models/fileupload_item.py +1 -1
  16. tableauserverclient/models/flow_item.py +54 -9
  17. tableauserverclient/models/flow_run_item.py +3 -3
  18. tableauserverclient/models/group_item.py +44 -4
  19. tableauserverclient/models/groupset_item.py +4 -4
  20. tableauserverclient/models/interval_item.py +9 -9
  21. tableauserverclient/models/job_item.py +73 -8
  22. tableauserverclient/models/linked_tasks_item.py +5 -5
  23. tableauserverclient/models/metric_item.py +5 -5
  24. tableauserverclient/models/pagination_item.py +1 -1
  25. tableauserverclient/models/permissions_item.py +12 -10
  26. tableauserverclient/models/project_item.py +73 -19
  27. tableauserverclient/models/property_decorators.py +12 -11
  28. tableauserverclient/models/reference_item.py +2 -2
  29. tableauserverclient/models/revision_item.py +3 -3
  30. tableauserverclient/models/schedule_item.py +2 -2
  31. tableauserverclient/models/server_info_item.py +26 -6
  32. tableauserverclient/models/site_item.py +69 -3
  33. tableauserverclient/models/subscription_item.py +3 -3
  34. tableauserverclient/models/table_item.py +1 -1
  35. tableauserverclient/models/tableau_auth.py +115 -5
  36. tableauserverclient/models/tableau_types.py +2 -2
  37. tableauserverclient/models/tag_item.py +3 -4
  38. tableauserverclient/models/task_item.py +34 -4
  39. tableauserverclient/models/user_item.py +47 -17
  40. tableauserverclient/models/view_item.py +66 -13
  41. tableauserverclient/models/virtual_connection_item.py +6 -5
  42. tableauserverclient/models/webhook_item.py +39 -6
  43. tableauserverclient/models/workbook_item.py +116 -13
  44. tableauserverclient/namespace.py +1 -1
  45. tableauserverclient/server/__init__.py +2 -1
  46. tableauserverclient/server/endpoint/auth_endpoint.py +69 -10
  47. tableauserverclient/server/endpoint/custom_views_endpoint.py +258 -29
  48. tableauserverclient/server/endpoint/data_acceleration_report_endpoint.py +2 -2
  49. tableauserverclient/server/endpoint/data_alert_endpoint.py +14 -14
  50. tableauserverclient/server/endpoint/databases_endpoint.py +13 -12
  51. tableauserverclient/server/endpoint/datasources_endpoint.py +61 -62
  52. tableauserverclient/server/endpoint/default_permissions_endpoint.py +19 -18
  53. tableauserverclient/server/endpoint/dqw_endpoint.py +9 -9
  54. tableauserverclient/server/endpoint/endpoint.py +19 -21
  55. tableauserverclient/server/endpoint/exceptions.py +23 -7
  56. tableauserverclient/server/endpoint/favorites_endpoint.py +31 -31
  57. tableauserverclient/server/endpoint/fileuploads_endpoint.py +9 -11
  58. tableauserverclient/server/endpoint/flow_runs_endpoint.py +15 -13
  59. tableauserverclient/server/endpoint/flow_task_endpoint.py +2 -2
  60. tableauserverclient/server/endpoint/flows_endpoint.py +344 -29
  61. tableauserverclient/server/endpoint/groups_endpoint.py +342 -27
  62. tableauserverclient/server/endpoint/groupsets_endpoint.py +2 -2
  63. tableauserverclient/server/endpoint/jobs_endpoint.py +116 -7
  64. tableauserverclient/server/endpoint/linked_tasks_endpoint.py +2 -2
  65. tableauserverclient/server/endpoint/metadata_endpoint.py +2 -2
  66. tableauserverclient/server/endpoint/metrics_endpoint.py +10 -10
  67. tableauserverclient/server/endpoint/permissions_endpoint.py +13 -15
  68. tableauserverclient/server/endpoint/projects_endpoint.py +681 -30
  69. tableauserverclient/server/endpoint/resource_tagger.py +14 -13
  70. tableauserverclient/server/endpoint/schedules_endpoint.py +17 -18
  71. tableauserverclient/server/endpoint/server_info_endpoint.py +40 -5
  72. tableauserverclient/server/endpoint/sites_endpoint.py +282 -17
  73. tableauserverclient/server/endpoint/subscriptions_endpoint.py +10 -10
  74. tableauserverclient/server/endpoint/tables_endpoint.py +15 -14
  75. tableauserverclient/server/endpoint/tasks_endpoint.py +86 -8
  76. tableauserverclient/server/endpoint/users_endpoint.py +366 -19
  77. tableauserverclient/server/endpoint/views_endpoint.py +262 -20
  78. tableauserverclient/server/endpoint/virtual_connections_endpoint.py +6 -5
  79. tableauserverclient/server/endpoint/webhooks_endpoint.py +88 -11
  80. tableauserverclient/server/endpoint/workbooks_endpoint.py +653 -65
  81. tableauserverclient/server/filter.py +2 -2
  82. tableauserverclient/server/pager.py +29 -6
  83. tableauserverclient/server/query.py +68 -19
  84. tableauserverclient/server/request_factory.py +57 -37
  85. tableauserverclient/server/request_options.py +243 -141
  86. tableauserverclient/server/server.py +76 -10
  87. tableauserverclient/server/sort.py +16 -2
  88. {tableauserverclient-0.33.dist-info → tableauserverclient-0.35.dist-info}/METADATA +7 -7
  89. tableauserverclient-0.35.dist-info/RECORD +106 -0
  90. {tableauserverclient-0.33.dist-info → tableauserverclient-0.35.dist-info}/WHEEL +1 -1
  91. tableauserverclient-0.33.dist-info/RECORD +0 -106
  92. {tableauserverclient-0.33.dist-info → tableauserverclient-0.35.dist-info}/LICENSE +0 -0
  93. {tableauserverclient-0.33.dist-info → tableauserverclient-0.35.dist-info}/LICENSE.versioneer +0 -0
  94. {tableauserverclient-0.33.dist-info → tableauserverclient-0.35.dist-info}/top_level.txt +0 -0
@@ -1,6 +1,7 @@
1
1
  import logging
2
2
  from contextlib import closing
3
3
 
4
+ from tableauserverclient.models.permissions_item import PermissionsRule
4
5
  from tableauserverclient.server.endpoint.endpoint import QuerysetEndpoint, api
5
6
  from tableauserverclient.server.endpoint.exceptions import MissingRequiredFieldError
6
7
  from tableauserverclient.server.endpoint.permissions_endpoint import _PermissionsEndpoint
@@ -11,7 +12,8 @@ from tableauserverclient.models import ViewItem, PaginationItem
11
12
 
12
13
  from tableauserverclient.helpers.logging import logger
13
14
 
14
- from typing import Iterable, Iterator, List, Optional, Set, Tuple, TYPE_CHECKING, Union
15
+ from typing import Optional, TYPE_CHECKING, Union
16
+ from collections.abc import Iterable, Iterator
15
17
 
16
18
  if TYPE_CHECKING:
17
19
  from tableauserverclient.server.request_options import (
@@ -24,23 +26,47 @@ if TYPE_CHECKING:
24
26
 
25
27
 
26
28
  class Views(QuerysetEndpoint[ViewItem], TaggingMixin[ViewItem]):
29
+ """
30
+ The Tableau Server Client provides methods for interacting with view
31
+ resources, or endpoints. These methods correspond to the endpoints for views
32
+ in the Tableau Server REST API.
33
+ """
34
+
27
35
  def __init__(self, parent_srv):
28
- super(Views, self).__init__(parent_srv)
36
+ super().__init__(parent_srv)
29
37
  self._permissions = _PermissionsEndpoint(parent_srv, lambda: self.baseurl)
30
38
 
31
39
  # Used because populate_preview_image functionaliy requires workbook endpoint
32
40
  @property
33
41
  def siteurl(self) -> str:
34
- return "{0}/sites/{1}".format(self.parent_srv.baseurl, self.parent_srv.site_id)
42
+ return f"{self.parent_srv.baseurl}/sites/{self.parent_srv.site_id}"
35
43
 
36
44
  @property
37
45
  def baseurl(self) -> str:
38
- return "{0}/views".format(self.siteurl)
46
+ return f"{self.siteurl}/views"
39
47
 
40
48
  @api(version="2.2")
41
49
  def get(
42
50
  self, req_options: Optional["RequestOptions"] = None, usage: bool = False
43
- ) -> Tuple[List[ViewItem], PaginationItem]:
51
+ ) -> tuple[list[ViewItem], PaginationItem]:
52
+ """
53
+ Returns the list of views on the site. Paginated endpoint.
54
+
55
+ REST API: https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref_workbooks_and_views.htm#query_views_for_site
56
+
57
+ Parameters
58
+ ----------
59
+ req_options: Optional[RequestOptions], default None
60
+ The request options for the request. These options can include
61
+ parameters such as page size and sorting.
62
+
63
+ usage: bool, default False
64
+ If True, includes usage statistics in the response.
65
+
66
+ Returns
67
+ -------
68
+ views: tuple[list[ViewItem], PaginationItem]
69
+ """
44
70
  logger.info("Querying all views on site")
45
71
  url = self.baseurl
46
72
  if usage:
@@ -52,11 +78,28 @@ class Views(QuerysetEndpoint[ViewItem], TaggingMixin[ViewItem]):
52
78
 
53
79
  @api(version="3.1")
54
80
  def get_by_id(self, view_id: str, usage: bool = False) -> ViewItem:
81
+ """
82
+ Returns the details of a specific view.
83
+
84
+ REST API: https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref_workbooks_and_views.htm#get_view
85
+
86
+ Parameters
87
+ ----------
88
+ view_id: str
89
+ The view ID.
90
+
91
+ usage: bool, default False
92
+ If True, includes usage statistics in the response.
93
+
94
+ Returns
95
+ -------
96
+ view_item: ViewItem
97
+ """
55
98
  if not view_id:
56
99
  error = "View item missing ID."
57
100
  raise MissingRequiredFieldError(error)
58
- logger.info("Querying single view (ID: {0})".format(view_id))
59
- url = "{0}/{1}".format(self.baseurl, view_id)
101
+ logger.info(f"Querying single view (ID: {view_id})")
102
+ url = f"{self.baseurl}/{view_id}"
60
103
  if usage:
61
104
  url += "?includeUsageStatistics=true"
62
105
  server_response = self.get_request(url)
@@ -64,6 +107,24 @@ class Views(QuerysetEndpoint[ViewItem], TaggingMixin[ViewItem]):
64
107
 
65
108
  @api(version="2.0")
66
109
  def populate_preview_image(self, view_item: ViewItem) -> None:
110
+ """
111
+ Populates a preview image for the specified view.
112
+
113
+ This method gets the preview image (thumbnail) for the specified view
114
+ item. The method uses the id and workbook_id fields to query the preview
115
+ image. The method populates the preview_image for the view.
116
+
117
+ REST API: https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref_workbooks_and_views.htm#query_view_with_preview
118
+
119
+ Parameters
120
+ ----------
121
+ view_item: ViewItem
122
+ The view item for which to populate the preview image.
123
+
124
+ Returns
125
+ -------
126
+ None
127
+ """
67
128
  if not view_item.id or not view_item.workbook_id:
68
129
  error = "View item missing ID or workbook ID."
69
130
  raise MissingRequiredFieldError(error)
@@ -72,16 +133,37 @@ class Views(QuerysetEndpoint[ViewItem], TaggingMixin[ViewItem]):
72
133
  return self._get_preview_for_view(view_item)
73
134
 
74
135
  view_item._set_preview_image(image_fetcher)
75
- logger.info("Populated preview image for view (ID: {0})".format(view_item.id))
136
+ logger.info(f"Populated preview image for view (ID: {view_item.id})")
76
137
 
77
138
  def _get_preview_for_view(self, view_item: ViewItem) -> bytes:
78
- url = "{0}/workbooks/{1}/views/{2}/previewImage".format(self.siteurl, view_item.workbook_id, view_item.id)
139
+ url = f"{self.siteurl}/workbooks/{view_item.workbook_id}/views/{view_item.id}/previewImage"
79
140
  server_response = self.get_request(url)
80
141
  image = server_response.content
81
142
  return image
82
143
 
83
144
  @api(version="2.5")
84
145
  def populate_image(self, view_item: ViewItem, req_options: Optional["ImageRequestOptions"] = None) -> None:
146
+ """
147
+ Populates the image of the specified view.
148
+
149
+ This method uses the id field to query the image, and populates the
150
+ image content as the image field.
151
+
152
+ REST API: https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref_workbooks_and_views.htm#query_view_image
153
+
154
+ Parameters
155
+ ----------
156
+ view_item: ViewItem
157
+ The view item for which to populate the image.
158
+
159
+ req_options: Optional[ImageRequestOptions], default None
160
+ Optional request options for the request. These options can include
161
+ parameters such as image resolution and max age.
162
+
163
+ Returns
164
+ -------
165
+ None
166
+ """
85
167
  if not view_item.id:
86
168
  error = "View item missing ID."
87
169
  raise MissingRequiredFieldError(error)
@@ -90,16 +172,36 @@ class Views(QuerysetEndpoint[ViewItem], TaggingMixin[ViewItem]):
90
172
  return self._get_view_image(view_item, req_options)
91
173
 
92
174
  view_item._set_image(image_fetcher)
93
- logger.info("Populated image for view (ID: {0})".format(view_item.id))
175
+ logger.info(f"Populated image for view (ID: {view_item.id})")
94
176
 
95
177
  def _get_view_image(self, view_item: ViewItem, req_options: Optional["ImageRequestOptions"]) -> bytes:
96
- url = "{0}/{1}/image".format(self.baseurl, view_item.id)
178
+ url = f"{self.baseurl}/{view_item.id}/image"
97
179
  server_response = self.get_request(url, req_options)
98
180
  image = server_response.content
99
181
  return image
100
182
 
101
183
  @api(version="2.7")
102
184
  def populate_pdf(self, view_item: ViewItem, req_options: Optional["PDFRequestOptions"] = None) -> None:
185
+ """
186
+ Populates the PDF content of the specified view.
187
+
188
+ This method populates a PDF with image(s) of the view you specify.
189
+
190
+ REST API: https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref_workbooks_and_views.htm#query_view_pdf
191
+
192
+ Parameters
193
+ ----------
194
+ view_item: ViewItem
195
+ The view item for which to populate the PDF.
196
+
197
+ req_options: Optional[PDFRequestOptions], default None
198
+ Optional request options for the request. These options can include
199
+ parameters such as orientation and paper size.
200
+
201
+ Returns
202
+ -------
203
+ None
204
+ """
103
205
  if not view_item.id:
104
206
  error = "View item missing ID."
105
207
  raise MissingRequiredFieldError(error)
@@ -108,16 +210,37 @@ class Views(QuerysetEndpoint[ViewItem], TaggingMixin[ViewItem]):
108
210
  return self._get_view_pdf(view_item, req_options)
109
211
 
110
212
  view_item._set_pdf(pdf_fetcher)
111
- logger.info("Populated pdf for view (ID: {0})".format(view_item.id))
213
+ logger.info(f"Populated pdf for view (ID: {view_item.id})")
112
214
 
113
215
  def _get_view_pdf(self, view_item: ViewItem, req_options: Optional["PDFRequestOptions"]) -> bytes:
114
- url = "{0}/{1}/pdf".format(self.baseurl, view_item.id)
216
+ url = f"{self.baseurl}/{view_item.id}/pdf"
115
217
  server_response = self.get_request(url, req_options)
116
218
  pdf = server_response.content
117
219
  return pdf
118
220
 
119
221
  @api(version="2.7")
120
222
  def populate_csv(self, view_item: ViewItem, req_options: Optional["CSVRequestOptions"] = None) -> None:
223
+ """
224
+ Populates the CSV data of the specified view.
225
+
226
+ This method uses the id field to query the CSV data, and populates the
227
+ data as the csv field.
228
+
229
+ REST API: https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref_workbooks_and_views.htm#query_view_data
230
+
231
+ Parameters
232
+ ----------
233
+ view_item: ViewItem
234
+ The view item for which to populate the CSV data.
235
+
236
+ req_options: Optional[CSVRequestOptions], default None
237
+ Optional request options for the request. These options can include
238
+ parameters such as view filters and max age.
239
+
240
+ Returns
241
+ -------
242
+ None
243
+ """
121
244
  if not view_item.id:
122
245
  error = "View item missing ID."
123
246
  raise MissingRequiredFieldError(error)
@@ -126,16 +249,37 @@ class Views(QuerysetEndpoint[ViewItem], TaggingMixin[ViewItem]):
126
249
  return self._get_view_csv(view_item, req_options)
127
250
 
128
251
  view_item._set_csv(csv_fetcher)
129
- logger.info("Populated csv for view (ID: {0})".format(view_item.id))
252
+ logger.info(f"Populated csv for view (ID: {view_item.id})")
130
253
 
131
254
  def _get_view_csv(self, view_item: ViewItem, req_options: Optional["CSVRequestOptions"]) -> Iterator[bytes]:
132
- url = "{0}/{1}/data".format(self.baseurl, view_item.id)
255
+ url = f"{self.baseurl}/{view_item.id}/data"
133
256
 
134
257
  with closing(self.get_request(url, request_object=req_options, parameters={"stream": True})) as server_response:
135
258
  yield from server_response.iter_content(1024)
136
259
 
137
260
  @api(version="3.8")
138
261
  def populate_excel(self, view_item: ViewItem, req_options: Optional["ExcelRequestOptions"] = None) -> None:
262
+ """
263
+ Populates the Excel data of the specified view.
264
+
265
+ This method uses the id field to query the Excel data, and populates the
266
+ data as the Excel field.
267
+
268
+ REST API: https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref_workbooks_and_views.htm#download_view_excel
269
+
270
+ Parameters
271
+ ----------
272
+ view_item: ViewItem
273
+ The view item for which to populate the Excel data.
274
+
275
+ req_options: Optional[ExcelRequestOptions], default None
276
+ Optional request options for the request. These options can include
277
+ parameters such as view filters and max age.
278
+
279
+ Returns
280
+ -------
281
+ None
282
+ """
139
283
  if not view_item.id:
140
284
  error = "View item missing ID."
141
285
  raise MissingRequiredFieldError(error)
@@ -144,28 +288,76 @@ class Views(QuerysetEndpoint[ViewItem], TaggingMixin[ViewItem]):
144
288
  return self._get_view_excel(view_item, req_options)
145
289
 
146
290
  view_item._set_excel(excel_fetcher)
147
- logger.info("Populated excel for view (ID: {0})".format(view_item.id))
291
+ logger.info(f"Populated excel for view (ID: {view_item.id})")
148
292
 
149
293
  def _get_view_excel(self, view_item: ViewItem, req_options: Optional["ExcelRequestOptions"]) -> Iterator[bytes]:
150
- url = "{0}/{1}/crosstab/excel".format(self.baseurl, view_item.id)
294
+ url = f"{self.baseurl}/{view_item.id}/crosstab/excel"
151
295
 
152
296
  with closing(self.get_request(url, request_object=req_options, parameters={"stream": True})) as server_response:
153
297
  yield from server_response.iter_content(1024)
154
298
 
155
299
  @api(version="3.2")
156
300
  def populate_permissions(self, item: ViewItem) -> None:
301
+ """
302
+ Returns a list of permissions for the specific view.
303
+
304
+ REST API: https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref_permissions.htm#query_view_permissions
305
+
306
+ Parameters
307
+ ----------
308
+ item: ViewItem
309
+ The view item for which to populate the permissions.
310
+
311
+ Returns
312
+ -------
313
+ None
314
+ """
157
315
  self._permissions.populate(item)
158
316
 
159
317
  @api(version="3.2")
160
- def update_permissions(self, resource, rules):
318
+ def update_permissions(self, resource: ViewItem, rules: list[PermissionsRule]) -> list[PermissionsRule]:
319
+ """ """
161
320
  return self._permissions.update(resource, rules)
162
321
 
163
322
  @api(version="3.2")
164
- def delete_permission(self, item, capability_item):
323
+ def delete_permission(self, item: ViewItem, capability_item: PermissionsRule) -> None:
324
+ """
325
+ Deletes permission to the specified view (also known as a sheet) for a
326
+ Tableau Server user or group.
327
+
328
+ REST API: https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref_permissions.htm#delete_view_permission
329
+
330
+ Parameters
331
+ ----------
332
+ item: ViewItem
333
+ The view item for which to delete the permission.
334
+
335
+ capability_item: PermissionsRule
336
+ The permission rule to delete.
337
+
338
+ Returns
339
+ -------
340
+ None
341
+ """
165
342
  return self._permissions.delete(item, capability_item)
166
343
 
167
344
  # Update view. Currently only tags can be updated
168
345
  def update(self, view_item: ViewItem) -> ViewItem:
346
+ """
347
+ Updates the tags for the specified view. All other fields are managed
348
+ through the WorkbookItem object.
349
+
350
+ REST API: https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref_workbooks_and_views.htm#add_tags_to_view
351
+
352
+ Parameters
353
+ ----------
354
+ view_item: ViewItem
355
+ The view item for which to update tags.
356
+
357
+ Returns
358
+ -------
359
+ ViewItem
360
+ """
169
361
  if not view_item.id:
170
362
  error = "View item missing ID. View must be retrieved from server first."
171
363
  raise MissingRequiredFieldError(error)
@@ -176,15 +368,65 @@ class Views(QuerysetEndpoint[ViewItem], TaggingMixin[ViewItem]):
176
368
  return view_item
177
369
 
178
370
  @api(version="1.0")
179
- def add_tags(self, item: Union[ViewItem, str], tags: Union[Iterable[str], str]) -> Set[str]:
371
+ def add_tags(self, item: Union[ViewItem, str], tags: Union[Iterable[str], str]) -> set[str]:
372
+ """
373
+ Adds tags to the specified view.
374
+
375
+ REST API: https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref_workbooks_and_views.htm#add_tags_to_view
376
+
377
+ Parameters
378
+ ----------
379
+ item: Union[ViewItem, str]
380
+ The view item or view ID to which to add tags.
381
+
382
+ tags: Union[Iterable[str], str]
383
+ The tags to add to the view.
384
+
385
+ Returns
386
+ -------
387
+ set[str]
388
+
389
+ """
180
390
  return super().add_tags(item, tags)
181
391
 
182
392
  @api(version="1.0")
183
393
  def delete_tags(self, item: Union[ViewItem, str], tags: Union[Iterable[str], str]) -> None:
394
+ """
395
+ Deletes tags from the specified view.
396
+
397
+ REST API: https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref_workbooks_and_views.htm#delete_tags_from_view
398
+
399
+ Parameters
400
+ ----------
401
+ item: Union[ViewItem, str]
402
+ The view item or view ID from which to delete tags.
403
+
404
+ tags: Union[Iterable[str], str]
405
+ The tags to delete from the view.
406
+
407
+ Returns
408
+ -------
409
+ None
410
+ """
184
411
  return super().delete_tags(item, tags)
185
412
 
186
413
  @api(version="1.0")
187
414
  def update_tags(self, item: ViewItem) -> None:
415
+ """
416
+ Updates the tags for the specified view. Any changes to the tags must
417
+ be made by editing the tags attribute of the view item.
418
+
419
+ REST API: https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref_workbooks_and_views.htm#add_tags_to_view
420
+
421
+ Parameters
422
+ ----------
423
+ item: ViewItem
424
+ The view item for which to update tags.
425
+
426
+ Returns
427
+ -------
428
+ None
429
+ """
188
430
  return super().update_tags(item)
189
431
 
190
432
  def filter(self, *invalid, page_size: Optional[int] = None, **kwargs) -> QuerySet[ViewItem]:
@@ -1,7 +1,8 @@
1
1
  from functools import partial
2
2
  import json
3
3
  from pathlib import Path
4
- from typing import Iterable, List, Optional, Set, TYPE_CHECKING, Tuple, Union
4
+ from typing import Optional, TYPE_CHECKING, Union
5
+ from collections.abc import Iterable
5
6
 
6
7
  from tableauserverclient.models.connection_item import ConnectionItem
7
8
  from tableauserverclient.models.pagination_item import PaginationItem
@@ -28,7 +29,7 @@ class VirtualConnections(QuerysetEndpoint[VirtualConnectionItem], TaggingMixin):
28
29
  return f"{self.parent_srv.baseurl}/sites/{self.parent_srv.site_id}/virtualConnections"
29
30
 
30
31
  @api(version="3.18")
31
- def get(self, req_options: Optional[RequestOptions] = None) -> Tuple[List[VirtualConnectionItem], PaginationItem]:
32
+ def get(self, req_options: Optional[RequestOptions] = None) -> tuple[list[VirtualConnectionItem], PaginationItem]:
32
33
  server_response = self.get_request(self.baseurl, req_options)
33
34
  pagination_item = PaginationItem.from_response(server_response.content, self.parent_srv.namespace)
34
35
  virtual_connections = VirtualConnectionItem.from_response(server_response.content, self.parent_srv.namespace)
@@ -44,7 +45,7 @@ class VirtualConnections(QuerysetEndpoint[VirtualConnectionItem], TaggingMixin):
44
45
 
45
46
  def _get_virtual_database_connections(
46
47
  self, virtual_connection: VirtualConnectionItem, req_options: Optional[RequestOptions] = None
47
- ) -> Tuple[List[ConnectionItem], PaginationItem]:
48
+ ) -> tuple[list[ConnectionItem], PaginationItem]:
48
49
  server_response = self.get_request(f"{self.baseurl}/{virtual_connection.id}/connections", req_options)
49
50
  connections = ConnectionItem.from_response(server_response.content, self.parent_srv.namespace)
50
51
  pagination_item = PaginationItem.from_response(server_response.content, self.parent_srv.namespace)
@@ -83,7 +84,7 @@ class VirtualConnections(QuerysetEndpoint[VirtualConnectionItem], TaggingMixin):
83
84
  @api(version="3.23")
84
85
  def get_revisions(
85
86
  self, virtual_connection: VirtualConnectionItem, req_options: Optional[RequestOptions] = None
86
- ) -> Tuple[List[RevisionItem], PaginationItem]:
87
+ ) -> tuple[list[RevisionItem], PaginationItem]:
87
88
  server_response = self.get_request(f"{self.baseurl}/{virtual_connection.id}/revisions", req_options)
88
89
  pagination_item = PaginationItem.from_response(server_response.content, self.parent_srv.namespace)
89
90
  revisions = RevisionItem.from_response(server_response.content, self.parent_srv.namespace, virtual_connection)
@@ -159,7 +160,7 @@ class VirtualConnections(QuerysetEndpoint[VirtualConnectionItem], TaggingMixin):
159
160
  @api(version="3.23")
160
161
  def add_tags(
161
162
  self, virtual_connection: Union[VirtualConnectionItem, str], tags: Union[Iterable[str], str]
162
- ) -> Set[str]:
163
+ ) -> set[str]:
163
164
  return super().add_tags(virtual_connection, tags)
164
165
 
165
166
  @api(version="3.23")
@@ -6,7 +6,7 @@ from tableauserverclient.models import WebhookItem, PaginationItem
6
6
 
7
7
  from tableauserverclient.helpers.logging import logger
8
8
 
9
- from typing import List, Optional, TYPE_CHECKING, Tuple
9
+ from typing import Optional, TYPE_CHECKING
10
10
 
11
11
  if TYPE_CHECKING:
12
12
  from ..server import Server
@@ -15,14 +15,29 @@ if TYPE_CHECKING:
15
15
 
16
16
  class Webhooks(Endpoint):
17
17
  def __init__(self, parent_srv: "Server") -> None:
18
- super(Webhooks, self).__init__(parent_srv)
18
+ super().__init__(parent_srv)
19
19
 
20
20
  @property
21
21
  def baseurl(self) -> str:
22
- return "{0}/sites/{1}/webhooks".format(self.parent_srv.baseurl, self.parent_srv.site_id)
22
+ return f"{self.parent_srv.baseurl}/sites/{self.parent_srv.site_id}/webhooks"
23
23
 
24
24
  @api(version="3.6")
25
- def get(self, req_options: Optional["RequestOptions"] = None) -> Tuple[List[WebhookItem], PaginationItem]:
25
+ def get(self, req_options: Optional["RequestOptions"] = None) -> tuple[list[WebhookItem], PaginationItem]:
26
+ """
27
+ Returns a list of all webhooks on the site.
28
+
29
+ REST API: https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#list_webhooks_for_site
30
+
31
+ Parameters
32
+ ----------
33
+ req_options : Optional[RequestOptions]
34
+ Filter and sorting options for the request.
35
+
36
+ Returns
37
+ -------
38
+ tuple[list[WebhookItem], PaginationItem]
39
+ A tuple of the list of webhooks and pagination item
40
+ """
26
41
  logger.info("Querying all Webhooks on site")
27
42
  url = self.baseurl
28
43
  server_response = self.get_request(url, req_options)
@@ -32,39 +47,101 @@ class Webhooks(Endpoint):
32
47
 
33
48
  @api(version="3.6")
34
49
  def get_by_id(self, webhook_id: str) -> WebhookItem:
50
+ """
51
+ Returns information about a specified Webhook.
52
+
53
+ Rest API: https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#get_webhook
54
+
55
+ Parameters
56
+ ----------
57
+ webhook_id : str
58
+ The ID of the webhook to query.
59
+
60
+ Returns
61
+ -------
62
+ WebhookItem
63
+ An object containing information about the webhook.
64
+ """
35
65
  if not webhook_id:
36
66
  error = "Webhook ID undefined."
37
67
  raise ValueError(error)
38
- logger.info("Querying single webhook (ID: {0})".format(webhook_id))
39
- url = "{0}/{1}".format(self.baseurl, webhook_id)
68
+ logger.info(f"Querying single webhook (ID: {webhook_id})")
69
+ url = f"{self.baseurl}/{webhook_id}"
40
70
  server_response = self.get_request(url)
41
71
  return WebhookItem.from_response(server_response.content, self.parent_srv.namespace)[0]
42
72
 
43
73
  @api(version="3.6")
44
74
  def delete(self, webhook_id: str) -> None:
75
+ """
76
+ Deletes a specified webhook.
77
+
78
+ REST API: https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#delete_webhook
79
+
80
+ Parameters
81
+ ----------
82
+ webhook_id : str
83
+ The ID of the webhook to delete.
84
+
85
+ Returns
86
+ -------
87
+ None
88
+ """
45
89
  if not webhook_id:
46
90
  error = "Webhook ID undefined."
47
91
  raise ValueError(error)
48
- url = "{0}/{1}".format(self.baseurl, webhook_id)
92
+ url = f"{self.baseurl}/{webhook_id}"
49
93
  self.delete_request(url)
50
- logger.info("Deleted single webhook (ID: {0})".format(webhook_id))
94
+ logger.info(f"Deleted single webhook (ID: {webhook_id})")
51
95
 
52
96
  @api(version="3.6")
53
97
  def create(self, webhook_item: WebhookItem) -> WebhookItem:
98
+ """
99
+ Creates a new webhook on the site.
100
+
101
+ REST API: https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#create_webhook
102
+
103
+ Parameters
104
+ ----------
105
+ webhook_item : WebhookItem
106
+ The webhook item to create.
107
+
108
+ Returns
109
+ -------
110
+ WebhookItem
111
+ An object containing information about the created webhook
112
+ """
54
113
  url = self.baseurl
55
114
  create_req = RequestFactory.Webhook.create_req(webhook_item)
56
115
  server_response = self.post_request(url, create_req)
57
116
  new_webhook = WebhookItem.from_response(server_response.content, self.parent_srv.namespace)[0]
58
117
 
59
- logger.info("Created new webhook (ID: {0})".format(new_webhook.id))
118
+ logger.info(f"Created new webhook (ID: {new_webhook.id})")
60
119
  return new_webhook
61
120
 
62
121
  @api(version="3.6")
63
122
  def test(self, webhook_id: str):
123
+ """
124
+ Tests the specified webhook. Sends an empty payload to the configured
125
+ destination URL of the webhook and returns the response from the server.
126
+ This is useful for testing, to ensure that things are being sent from
127
+ Tableau and received back as expected.
128
+
129
+ Rest API: https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#test_webhook
130
+
131
+ Parameters
132
+ ----------
133
+ webhook_id : str
134
+ The ID of the webhook to test.
135
+
136
+ Returns
137
+ -------
138
+ XML Response
139
+
140
+ """
64
141
  if not webhook_id:
65
142
  error = "Webhook ID undefined."
66
143
  raise ValueError(error)
67
- url = "{0}/{1}/test".format(self.baseurl, webhook_id)
144
+ url = f"{self.baseurl}/{webhook_id}/test"
68
145
  testOutcome = self.get_request(url)
69
- logger.info("Testing webhook (ID: {0} returned {1})".format(webhook_id, testOutcome))
146
+ logger.info(f"Testing webhook (ID: {webhook_id} returned {testOutcome})")
70
147
  return testOutcome