tableauserverclient 0.36__py3-none-any.whl → 0.38__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 +6 -0
- tableauserverclient/bin/_version.py +3 -3
- tableauserverclient/helpers/strings.py +25 -1
- tableauserverclient/models/__init__.py +6 -1
- tableauserverclient/models/connection_item.py +3 -3
- tableauserverclient/models/datasource_item.py +218 -23
- tableauserverclient/models/extract_item.py +82 -0
- tableauserverclient/models/flow_item.py +2 -2
- tableauserverclient/models/group_item.py +11 -0
- tableauserverclient/models/interval_item.py +40 -0
- tableauserverclient/models/job_item.py +1 -0
- tableauserverclient/models/location_item.py +53 -0
- tableauserverclient/models/project_item.py +138 -27
- tableauserverclient/models/schedule_item.py +57 -0
- tableauserverclient/models/site_item.py +28 -0
- tableauserverclient/models/table_item.py +7 -3
- tableauserverclient/models/tableau_types.py +13 -1
- tableauserverclient/models/user_item.py +101 -1
- tableauserverclient/models/view_item.py +79 -5
- tableauserverclient/models/workbook_item.py +151 -1
- tableauserverclient/server/__init__.py +2 -0
- tableauserverclient/server/endpoint/databases_endpoint.py +101 -18
- tableauserverclient/server/endpoint/datasources_endpoint.py +562 -7
- tableauserverclient/server/endpoint/dqw_endpoint.py +16 -6
- tableauserverclient/server/endpoint/endpoint.py +39 -0
- tableauserverclient/server/endpoint/exceptions.py +4 -0
- tableauserverclient/server/endpoint/fileuploads_endpoint.py +1 -1
- tableauserverclient/server/endpoint/groupsets_endpoint.py +2 -2
- tableauserverclient/server/endpoint/jobs_endpoint.py +1 -1
- tableauserverclient/server/endpoint/schedules_endpoint.py +132 -2
- tableauserverclient/server/endpoint/sites_endpoint.py +18 -1
- tableauserverclient/server/endpoint/tables_endpoint.py +140 -17
- tableauserverclient/server/endpoint/users_endpoint.py +22 -5
- tableauserverclient/server/endpoint/views_endpoint.py +5 -1
- tableauserverclient/server/endpoint/workbooks_endpoint.py +24 -10
- tableauserverclient/server/query.py +36 -0
- tableauserverclient/server/request_factory.py +16 -5
- tableauserverclient/server/request_options.py +162 -2
- tableauserverclient/server/server.py +42 -0
- {tableauserverclient-0.36.dist-info → tableauserverclient-0.38.dist-info}/METADATA +3 -2
- {tableauserverclient-0.36.dist-info → tableauserverclient-0.38.dist-info}/RECORD +45 -43
- {tableauserverclient-0.36.dist-info → tableauserverclient-0.38.dist-info}/WHEEL +1 -1
- {tableauserverclient-0.36.dist-info → tableauserverclient-0.38.dist-info/licenses}/LICENSE +0 -0
- {tableauserverclient-0.36.dist-info → tableauserverclient-0.38.dist-info/licenses}/LICENSE.versioneer +0 -0
- {tableauserverclient-0.36.dist-info → tableauserverclient-0.38.dist-info}/top_level.txt +0 -0
|
@@ -7,6 +7,7 @@ from typing import Optional, TYPE_CHECKING
|
|
|
7
7
|
from defusedxml.ElementTree import fromstring
|
|
8
8
|
|
|
9
9
|
from tableauserverclient.datetime_helpers import parse_datetime
|
|
10
|
+
from tableauserverclient.models.site_item import SiteAuthConfiguration
|
|
10
11
|
from .exceptions import UnpopulatedPropertyError
|
|
11
12
|
from .property_decorators import (
|
|
12
13
|
property_is_enum,
|
|
@@ -37,6 +38,49 @@ class UserItem:
|
|
|
37
38
|
auth_setting: str
|
|
38
39
|
Required attribute for Tableau Cloud. How the user autenticates to the
|
|
39
40
|
server.
|
|
41
|
+
|
|
42
|
+
Attributes
|
|
43
|
+
----------
|
|
44
|
+
domain_name: Optional[str]
|
|
45
|
+
The name of the Active Directory domain ("local" if local authentication
|
|
46
|
+
is used).
|
|
47
|
+
|
|
48
|
+
email: Optional[str]
|
|
49
|
+
The email address of the user.
|
|
50
|
+
|
|
51
|
+
external_auth_user_id: Optional[str]
|
|
52
|
+
The unique identifier for the user in the external authentication system.
|
|
53
|
+
|
|
54
|
+
id: Optional[str]
|
|
55
|
+
The unique identifier for the user.
|
|
56
|
+
|
|
57
|
+
favorites: dict[str, list]
|
|
58
|
+
The favorites of the user. Must be populated with a call to
|
|
59
|
+
`populate_favorites()`.
|
|
60
|
+
|
|
61
|
+
fullname: Optional[str]
|
|
62
|
+
The full name of the user.
|
|
63
|
+
|
|
64
|
+
groups: Pager
|
|
65
|
+
The groups the user belongs to. Must be populated with a call to
|
|
66
|
+
`populate_groups()`.
|
|
67
|
+
|
|
68
|
+
last_login: Optional[datetime]
|
|
69
|
+
The last time the user logged in.
|
|
70
|
+
|
|
71
|
+
locale: Optional[str]
|
|
72
|
+
The locale of the user.
|
|
73
|
+
|
|
74
|
+
language: Optional[str]
|
|
75
|
+
Language setting for the user.
|
|
76
|
+
|
|
77
|
+
idp_configuration_id: Optional[str]
|
|
78
|
+
The ID of the identity provider configuration.
|
|
79
|
+
|
|
80
|
+
workbooks: Pager
|
|
81
|
+
The workbooks owned by the user. Must be populated with a call to
|
|
82
|
+
`populate_workbooks()`.
|
|
83
|
+
|
|
40
84
|
"""
|
|
41
85
|
|
|
42
86
|
tag_name: str = "user"
|
|
@@ -94,6 +138,9 @@ class UserItem:
|
|
|
94
138
|
self.name: Optional[str] = name
|
|
95
139
|
self.site_role: Optional[str] = site_role
|
|
96
140
|
self.auth_setting: Optional[str] = auth_setting
|
|
141
|
+
self._locale: Optional[str] = None
|
|
142
|
+
self._language: Optional[str] = None
|
|
143
|
+
self._idp_configuration_id: Optional[str] = None
|
|
97
144
|
|
|
98
145
|
return None
|
|
99
146
|
|
|
@@ -184,6 +231,26 @@ class UserItem:
|
|
|
184
231
|
raise UnpopulatedPropertyError(error)
|
|
185
232
|
return self._groups()
|
|
186
233
|
|
|
234
|
+
@property
|
|
235
|
+
def locale(self) -> Optional[str]:
|
|
236
|
+
return self._locale
|
|
237
|
+
|
|
238
|
+
@property
|
|
239
|
+
def language(self) -> Optional[str]:
|
|
240
|
+
return self._language
|
|
241
|
+
|
|
242
|
+
@property
|
|
243
|
+
def idp_configuration_id(self) -> Optional[str]:
|
|
244
|
+
"""
|
|
245
|
+
IDP configuration id for the user. This is only available on Tableau
|
|
246
|
+
Cloud, 3.24 or later
|
|
247
|
+
"""
|
|
248
|
+
return self._idp_configuration_id
|
|
249
|
+
|
|
250
|
+
@idp_configuration_id.setter
|
|
251
|
+
def idp_configuration_id(self, value: str) -> None:
|
|
252
|
+
self._idp_configuration_id = value
|
|
253
|
+
|
|
187
254
|
def _set_workbooks(self, workbooks) -> None:
|
|
188
255
|
self._workbooks = workbooks
|
|
189
256
|
|
|
@@ -204,8 +271,11 @@ class UserItem:
|
|
|
204
271
|
email,
|
|
205
272
|
auth_setting,
|
|
206
273
|
_,
|
|
274
|
+
_,
|
|
275
|
+
_,
|
|
276
|
+
_,
|
|
207
277
|
) = self._parse_element(user_xml, ns)
|
|
208
|
-
self._set_values(None, None, site_role, None, None, fullname, email, auth_setting, None)
|
|
278
|
+
self._set_values(None, None, site_role, None, None, fullname, email, auth_setting, None, None, None, None)
|
|
209
279
|
return self
|
|
210
280
|
|
|
211
281
|
def _set_values(
|
|
@@ -219,6 +289,9 @@ class UserItem:
|
|
|
219
289
|
email,
|
|
220
290
|
auth_setting,
|
|
221
291
|
domain_name,
|
|
292
|
+
locale,
|
|
293
|
+
language,
|
|
294
|
+
idp_configuration_id,
|
|
222
295
|
):
|
|
223
296
|
if id is not None:
|
|
224
297
|
self._id = id
|
|
@@ -238,6 +311,12 @@ class UserItem:
|
|
|
238
311
|
self._auth_setting = auth_setting
|
|
239
312
|
if domain_name:
|
|
240
313
|
self._domain_name = domain_name
|
|
314
|
+
if locale:
|
|
315
|
+
self._locale = locale
|
|
316
|
+
if language:
|
|
317
|
+
self._language = language
|
|
318
|
+
if idp_configuration_id:
|
|
319
|
+
self._idp_configuration_id = idp_configuration_id
|
|
241
320
|
|
|
242
321
|
@classmethod
|
|
243
322
|
def from_response(cls, resp, ns) -> list["UserItem"]:
|
|
@@ -249,6 +328,12 @@ class UserItem:
|
|
|
249
328
|
element_name = ".//t:owner"
|
|
250
329
|
return cls._parse_xml(element_name, resp, ns)
|
|
251
330
|
|
|
331
|
+
@classmethod
|
|
332
|
+
def from_xml(cls, xml: ET.Element, ns: Optional[dict] = None) -> "UserItem":
|
|
333
|
+
item = cls()
|
|
334
|
+
item._set_values(*cls._parse_element(xml, ns))
|
|
335
|
+
return item
|
|
336
|
+
|
|
252
337
|
@classmethod
|
|
253
338
|
def _parse_xml(cls, element_name, resp, ns):
|
|
254
339
|
all_user_items = []
|
|
@@ -265,6 +350,9 @@ class UserItem:
|
|
|
265
350
|
email,
|
|
266
351
|
auth_setting,
|
|
267
352
|
domain_name,
|
|
353
|
+
locale,
|
|
354
|
+
language,
|
|
355
|
+
idp_configuration_id,
|
|
268
356
|
) = cls._parse_element(user_xml, ns)
|
|
269
357
|
user_item = cls(name, site_role)
|
|
270
358
|
user_item._set_values(
|
|
@@ -277,6 +365,9 @@ class UserItem:
|
|
|
277
365
|
email,
|
|
278
366
|
auth_setting,
|
|
279
367
|
domain_name,
|
|
368
|
+
locale,
|
|
369
|
+
language,
|
|
370
|
+
idp_configuration_id,
|
|
280
371
|
)
|
|
281
372
|
all_user_items.append(user_item)
|
|
282
373
|
return all_user_items
|
|
@@ -295,6 +386,9 @@ class UserItem:
|
|
|
295
386
|
fullname = user_xml.get("fullName", None)
|
|
296
387
|
email = user_xml.get("email", None)
|
|
297
388
|
auth_setting = user_xml.get("authSetting", None)
|
|
389
|
+
locale = user_xml.get("locale", None)
|
|
390
|
+
language = user_xml.get("language", None)
|
|
391
|
+
idp_configuration_id = user_xml.get("idpConfigurationId", None)
|
|
298
392
|
|
|
299
393
|
domain_name = None
|
|
300
394
|
domain_elem = user_xml.find(".//t:domain", namespaces=ns)
|
|
@@ -311,6 +405,9 @@ class UserItem:
|
|
|
311
405
|
email,
|
|
312
406
|
auth_setting,
|
|
313
407
|
domain_name,
|
|
408
|
+
locale,
|
|
409
|
+
language,
|
|
410
|
+
idp_configuration_id,
|
|
314
411
|
)
|
|
315
412
|
|
|
316
413
|
class CSVImport:
|
|
@@ -361,6 +458,9 @@ class UserItem:
|
|
|
361
458
|
values[UserItem.CSVImport.ColumnType.EMAIL],
|
|
362
459
|
values[UserItem.CSVImport.ColumnType.AUTH],
|
|
363
460
|
None,
|
|
461
|
+
None,
|
|
462
|
+
None,
|
|
463
|
+
None,
|
|
364
464
|
)
|
|
365
465
|
return user
|
|
366
466
|
|
|
@@ -1,15 +1,21 @@
|
|
|
1
1
|
import copy
|
|
2
2
|
from datetime import datetime
|
|
3
3
|
from requests import Response
|
|
4
|
-
from typing import Callable, Optional
|
|
4
|
+
from typing import TYPE_CHECKING, Callable, Optional, overload
|
|
5
5
|
from collections.abc import Iterator
|
|
6
6
|
|
|
7
7
|
from defusedxml.ElementTree import fromstring
|
|
8
8
|
|
|
9
9
|
from tableauserverclient.datetime_helpers import parse_datetime
|
|
10
10
|
from tableauserverclient.models.exceptions import UnpopulatedPropertyError
|
|
11
|
+
from tableauserverclient.models.location_item import LocationItem
|
|
11
12
|
from tableauserverclient.models.permissions_item import PermissionsRule
|
|
13
|
+
from tableauserverclient.models.project_item import ProjectItem
|
|
12
14
|
from tableauserverclient.models.tag_item import TagItem
|
|
15
|
+
from tableauserverclient.models.user_item import UserItem
|
|
16
|
+
|
|
17
|
+
if TYPE_CHECKING:
|
|
18
|
+
from tableauserverclient.models.workbook_item import WorkbookItem
|
|
13
19
|
|
|
14
20
|
|
|
15
21
|
class ViewItem:
|
|
@@ -34,9 +40,16 @@ class ViewItem:
|
|
|
34
40
|
The image of the view. You must first call the `views.populate_image`
|
|
35
41
|
method to access the image.
|
|
36
42
|
|
|
43
|
+
location: Optional[LocationItem], default None
|
|
44
|
+
The location of the view. The location can be a personal space or a
|
|
45
|
+
project.
|
|
46
|
+
|
|
37
47
|
name: Optional[str], default None
|
|
38
48
|
The name of the view.
|
|
39
49
|
|
|
50
|
+
owner: Optional[UserItem], default None
|
|
51
|
+
The owner of the view.
|
|
52
|
+
|
|
40
53
|
owner_id: Optional[str], default None
|
|
41
54
|
The ID for the owner of the view.
|
|
42
55
|
|
|
@@ -48,6 +61,9 @@ class ViewItem:
|
|
|
48
61
|
The preview image of the view. You must first call the
|
|
49
62
|
`views.populate_preview_image` method to access the preview image.
|
|
50
63
|
|
|
64
|
+
project: Optional[ProjectItem], default None
|
|
65
|
+
The project that contains the view.
|
|
66
|
+
|
|
51
67
|
project_id: Optional[str], default None
|
|
52
68
|
The ID for the project that contains the view.
|
|
53
69
|
|
|
@@ -60,9 +76,11 @@ class ViewItem:
|
|
|
60
76
|
updated_at: Optional[datetime], default None
|
|
61
77
|
The date and time when the view was last updated.
|
|
62
78
|
|
|
79
|
+
workbook: Optional[WorkbookItem], default None
|
|
80
|
+
The workbook that contains the view.
|
|
81
|
+
|
|
63
82
|
workbook_id: Optional[str], default None
|
|
64
83
|
The ID for the workbook that contains the view.
|
|
65
|
-
|
|
66
84
|
"""
|
|
67
85
|
|
|
68
86
|
def __init__(self) -> None:
|
|
@@ -84,11 +102,18 @@ class ViewItem:
|
|
|
84
102
|
self._workbook_id: Optional[str] = None
|
|
85
103
|
self._permissions: Optional[Callable[[], list[PermissionsRule]]] = None
|
|
86
104
|
self.tags: set[str] = set()
|
|
105
|
+
self._favorites_total: Optional[int] = None
|
|
106
|
+
self._view_url_name: Optional[str] = None
|
|
87
107
|
self._data_acceleration_config = {
|
|
88
108
|
"acceleration_enabled": None,
|
|
89
109
|
"acceleration_status": None,
|
|
90
110
|
}
|
|
91
111
|
|
|
112
|
+
self._owner: Optional[UserItem] = None
|
|
113
|
+
self._project: Optional[ProjectItem] = None
|
|
114
|
+
self._workbook: Optional["WorkbookItem"] = None
|
|
115
|
+
self._location: Optional[LocationItem] = None
|
|
116
|
+
|
|
92
117
|
def __str__(self):
|
|
93
118
|
return "<ViewItem {} '{}' contentUrl='{}' project={}>".format(
|
|
94
119
|
self._id, self.name, self.content_url, self.project_id
|
|
@@ -190,6 +215,14 @@ class ViewItem:
|
|
|
190
215
|
def workbook_id(self) -> Optional[str]:
|
|
191
216
|
return self._workbook_id
|
|
192
217
|
|
|
218
|
+
@property
|
|
219
|
+
def view_url_name(self) -> Optional[str]:
|
|
220
|
+
return self._view_url_name
|
|
221
|
+
|
|
222
|
+
@property
|
|
223
|
+
def favorites_total(self) -> Optional[int]:
|
|
224
|
+
return self._favorites_total
|
|
225
|
+
|
|
193
226
|
@property
|
|
194
227
|
def data_acceleration_config(self):
|
|
195
228
|
return self._data_acceleration_config
|
|
@@ -198,6 +231,22 @@ class ViewItem:
|
|
|
198
231
|
def data_acceleration_config(self, value):
|
|
199
232
|
self._data_acceleration_config = value
|
|
200
233
|
|
|
234
|
+
@property
|
|
235
|
+
def project(self) -> Optional["ProjectItem"]:
|
|
236
|
+
return self._project
|
|
237
|
+
|
|
238
|
+
@property
|
|
239
|
+
def workbook(self) -> Optional["WorkbookItem"]:
|
|
240
|
+
return self._workbook
|
|
241
|
+
|
|
242
|
+
@property
|
|
243
|
+
def owner(self) -> Optional[UserItem]:
|
|
244
|
+
return self._owner
|
|
245
|
+
|
|
246
|
+
@property
|
|
247
|
+
def location(self) -> Optional[LocationItem]:
|
|
248
|
+
return self._location
|
|
249
|
+
|
|
201
250
|
@property
|
|
202
251
|
def permissions(self) -> list[PermissionsRule]:
|
|
203
252
|
if self._permissions is None:
|
|
@@ -228,7 +277,7 @@ class ViewItem:
|
|
|
228
277
|
workbook_elem = view_xml.find(".//t:workbook", namespaces=ns)
|
|
229
278
|
owner_elem = view_xml.find(".//t:owner", namespaces=ns)
|
|
230
279
|
project_elem = view_xml.find(".//t:project", namespaces=ns)
|
|
231
|
-
tags_elem = view_xml.find("
|
|
280
|
+
tags_elem = view_xml.find("./t:tags", namespaces=ns)
|
|
232
281
|
data_acceleration_config_elem = view_xml.find(".//t:dataAccelerationConfig", namespaces=ns)
|
|
233
282
|
view_item._created_at = parse_datetime(view_xml.get("createdAt", None))
|
|
234
283
|
view_item._updated_at = parse_datetime(view_xml.get("updatedAt", None))
|
|
@@ -236,22 +285,35 @@ class ViewItem:
|
|
|
236
285
|
view_item._name = view_xml.get("name", None)
|
|
237
286
|
view_item._content_url = view_xml.get("contentUrl", None)
|
|
238
287
|
view_item._sheet_type = view_xml.get("sheetType", None)
|
|
288
|
+
view_item._favorites_total = string_to_int(view_xml.get("favoritesTotal", None))
|
|
289
|
+
view_item._view_url_name = view_xml.get("viewUrlName", None)
|
|
239
290
|
if usage_elem is not None:
|
|
240
291
|
total_view = usage_elem.get("totalViewCount", None)
|
|
241
292
|
if total_view:
|
|
242
293
|
view_item._total_views = int(total_view)
|
|
243
294
|
if owner_elem is not None:
|
|
295
|
+
user = UserItem.from_xml(owner_elem, ns)
|
|
296
|
+
view_item._owner = user
|
|
244
297
|
view_item._owner_id = owner_elem.get("id", None)
|
|
245
298
|
if project_elem is not None:
|
|
246
|
-
|
|
299
|
+
project_item = ProjectItem.from_xml(project_elem, ns)
|
|
300
|
+
view_item._project = project_item
|
|
301
|
+
view_item._project_id = project_item.id
|
|
247
302
|
if workbook_id:
|
|
248
303
|
view_item._workbook_id = workbook_id
|
|
249
304
|
elif workbook_elem is not None:
|
|
250
|
-
|
|
305
|
+
from tableauserverclient.models.workbook_item import WorkbookItem
|
|
306
|
+
|
|
307
|
+
workbook_item = WorkbookItem.from_xml(workbook_elem, ns)
|
|
308
|
+
view_item._workbook = workbook_item
|
|
309
|
+
view_item._workbook_id = workbook_item.id
|
|
251
310
|
if tags_elem is not None:
|
|
252
311
|
tags = TagItem.from_xml_element(tags_elem, ns)
|
|
253
312
|
view_item.tags = tags
|
|
254
313
|
view_item._initial_tags = copy.copy(tags)
|
|
314
|
+
if (location_elem := view_xml.find(".//t:location", namespaces=ns)) is not None:
|
|
315
|
+
location = LocationItem.from_xml(location_elem, ns)
|
|
316
|
+
view_item._location = location
|
|
255
317
|
if data_acceleration_config_elem is not None:
|
|
256
318
|
data_acceleration_config = parse_data_acceleration_config(data_acceleration_config_elem)
|
|
257
319
|
view_item.data_acceleration_config = data_acceleration_config
|
|
@@ -274,3 +336,15 @@ def parse_data_acceleration_config(data_acceleration_elem):
|
|
|
274
336
|
|
|
275
337
|
def string_to_bool(s: str) -> bool:
|
|
276
338
|
return s.lower() == "true"
|
|
339
|
+
|
|
340
|
+
|
|
341
|
+
@overload
|
|
342
|
+
def string_to_int(s: None) -> None: ...
|
|
343
|
+
|
|
344
|
+
|
|
345
|
+
@overload
|
|
346
|
+
def string_to_int(s: str) -> int: ...
|
|
347
|
+
|
|
348
|
+
|
|
349
|
+
def string_to_int(s):
|
|
350
|
+
return int(s) if s is not None else None
|
|
@@ -2,11 +2,14 @@ import copy
|
|
|
2
2
|
import datetime
|
|
3
3
|
import uuid
|
|
4
4
|
import xml.etree.ElementTree as ET
|
|
5
|
-
from typing import Callable, Optional
|
|
5
|
+
from typing import Callable, Optional, overload
|
|
6
6
|
|
|
7
7
|
from defusedxml.ElementTree import fromstring
|
|
8
8
|
|
|
9
9
|
from tableauserverclient.datetime_helpers import parse_datetime
|
|
10
|
+
from tableauserverclient.models.location_item import LocationItem
|
|
11
|
+
from tableauserverclient.models.project_item import ProjectItem
|
|
12
|
+
from tableauserverclient.models.user_item import UserItem
|
|
10
13
|
from .connection_item import ConnectionItem
|
|
11
14
|
from .exceptions import UnpopulatedPropertyError
|
|
12
15
|
from .permissions_item import PermissionsRule
|
|
@@ -51,13 +54,31 @@ class WorkbookItem:
|
|
|
51
54
|
created_at : Optional[datetime.datetime]
|
|
52
55
|
The date and time the workbook was created.
|
|
53
56
|
|
|
57
|
+
default_view_id : Optional[str]
|
|
58
|
+
The identifier for the default view of the workbook.
|
|
59
|
+
|
|
54
60
|
description : Optional[str]
|
|
55
61
|
User-defined description of the workbook.
|
|
56
62
|
|
|
63
|
+
encrypt_extracts : Optional[bool]
|
|
64
|
+
Indicates whether extracts are encrypted.
|
|
65
|
+
|
|
66
|
+
has_extracts : Optional[bool]
|
|
67
|
+
Indicates whether the workbook has extracts.
|
|
68
|
+
|
|
57
69
|
id : Optional[str]
|
|
58
70
|
The identifier for the workbook. You need this value to query a specific
|
|
59
71
|
workbook or to delete a workbook with the get_by_id and delete methods.
|
|
60
72
|
|
|
73
|
+
last_published_at : Optional[datetime.datetime]
|
|
74
|
+
The date and time the workbook was last published.
|
|
75
|
+
|
|
76
|
+
location : Optional[LocationItem]
|
|
77
|
+
The location of the workbook, such as a personal space or project.
|
|
78
|
+
|
|
79
|
+
owner : Optional[UserItem]
|
|
80
|
+
The owner of the workbook.
|
|
81
|
+
|
|
61
82
|
owner_id : Optional[str]
|
|
62
83
|
The identifier for the owner (UserItem) of the workbook.
|
|
63
84
|
|
|
@@ -65,6 +86,9 @@ class WorkbookItem:
|
|
|
65
86
|
The thumbnail image for the view. You must first call the
|
|
66
87
|
workbooks.populate_preview_image method to access this data.
|
|
67
88
|
|
|
89
|
+
project: Optional[ProjectItem]
|
|
90
|
+
The project that contains the workbook.
|
|
91
|
+
|
|
68
92
|
project_name : Optional[str]
|
|
69
93
|
The name of the project that contains the workbook.
|
|
70
94
|
|
|
@@ -139,6 +163,15 @@ class WorkbookItem:
|
|
|
139
163
|
self._permissions = None
|
|
140
164
|
self.thumbnails_user_id = thumbnails_user_id
|
|
141
165
|
self.thumbnails_group_id = thumbnails_group_id
|
|
166
|
+
self._sheet_count: Optional[int] = None
|
|
167
|
+
self._has_extracts: Optional[bool] = None
|
|
168
|
+
self._project: Optional[ProjectItem] = None
|
|
169
|
+
self._owner: Optional[UserItem] = None
|
|
170
|
+
self._location: Optional[LocationItem] = None
|
|
171
|
+
self._encrypt_extracts: Optional[bool] = None
|
|
172
|
+
self._default_view_id: Optional[str] = None
|
|
173
|
+
self._share_description: Optional[str] = None
|
|
174
|
+
self._last_published_at: Optional[datetime.datetime] = None
|
|
142
175
|
|
|
143
176
|
return None
|
|
144
177
|
|
|
@@ -234,6 +267,14 @@ class WorkbookItem:
|
|
|
234
267
|
def size(self):
|
|
235
268
|
return self._size
|
|
236
269
|
|
|
270
|
+
@property
|
|
271
|
+
def sheet_count(self) -> Optional[int]:
|
|
272
|
+
return self._sheet_count
|
|
273
|
+
|
|
274
|
+
@property
|
|
275
|
+
def has_extracts(self) -> Optional[bool]:
|
|
276
|
+
return self._has_extracts
|
|
277
|
+
|
|
237
278
|
@property
|
|
238
279
|
def updated_at(self) -> Optional[datetime.datetime]:
|
|
239
280
|
return self._updated_at
|
|
@@ -300,6 +341,34 @@ class WorkbookItem:
|
|
|
300
341
|
def thumbnails_group_id(self, value: str):
|
|
301
342
|
self._thumbnails_group_id = value
|
|
302
343
|
|
|
344
|
+
@property
|
|
345
|
+
def project(self) -> Optional[ProjectItem]:
|
|
346
|
+
return self._project
|
|
347
|
+
|
|
348
|
+
@property
|
|
349
|
+
def owner(self) -> Optional[UserItem]:
|
|
350
|
+
return self._owner
|
|
351
|
+
|
|
352
|
+
@property
|
|
353
|
+
def location(self) -> Optional[LocationItem]:
|
|
354
|
+
return self._location
|
|
355
|
+
|
|
356
|
+
@property
|
|
357
|
+
def encrypt_extracts(self) -> Optional[bool]:
|
|
358
|
+
return self._encrypt_extracts
|
|
359
|
+
|
|
360
|
+
@property
|
|
361
|
+
def default_view_id(self) -> Optional[str]:
|
|
362
|
+
return self._default_view_id
|
|
363
|
+
|
|
364
|
+
@property
|
|
365
|
+
def share_description(self) -> Optional[str]:
|
|
366
|
+
return self._share_description
|
|
367
|
+
|
|
368
|
+
@property
|
|
369
|
+
def last_published_at(self) -> Optional[datetime.datetime]:
|
|
370
|
+
return self._last_published_at
|
|
371
|
+
|
|
303
372
|
def _set_connections(self, connections):
|
|
304
373
|
self._connections = connections
|
|
305
374
|
|
|
@@ -342,6 +411,15 @@ class WorkbookItem:
|
|
|
342
411
|
views,
|
|
343
412
|
data_acceleration_config,
|
|
344
413
|
data_freshness_policy,
|
|
414
|
+
sheet_count,
|
|
415
|
+
has_extracts,
|
|
416
|
+
project,
|
|
417
|
+
owner,
|
|
418
|
+
location,
|
|
419
|
+
encrypt_extracts,
|
|
420
|
+
default_view_id,
|
|
421
|
+
share_description,
|
|
422
|
+
last_published_at,
|
|
345
423
|
) = self._parse_element(workbook_xml, ns)
|
|
346
424
|
|
|
347
425
|
self._set_values(
|
|
@@ -361,6 +439,15 @@ class WorkbookItem:
|
|
|
361
439
|
views,
|
|
362
440
|
data_acceleration_config,
|
|
363
441
|
data_freshness_policy,
|
|
442
|
+
sheet_count,
|
|
443
|
+
has_extracts,
|
|
444
|
+
project,
|
|
445
|
+
owner,
|
|
446
|
+
location,
|
|
447
|
+
encrypt_extracts,
|
|
448
|
+
default_view_id,
|
|
449
|
+
share_description,
|
|
450
|
+
last_published_at,
|
|
364
451
|
)
|
|
365
452
|
|
|
366
453
|
return self
|
|
@@ -383,6 +470,15 @@ class WorkbookItem:
|
|
|
383
470
|
views,
|
|
384
471
|
data_acceleration_config,
|
|
385
472
|
data_freshness_policy,
|
|
473
|
+
sheet_count,
|
|
474
|
+
has_extracts,
|
|
475
|
+
project,
|
|
476
|
+
owner,
|
|
477
|
+
location,
|
|
478
|
+
encrypt_extracts,
|
|
479
|
+
default_view_id,
|
|
480
|
+
share_description,
|
|
481
|
+
last_published_at,
|
|
386
482
|
):
|
|
387
483
|
if id is not None:
|
|
388
484
|
self._id = id
|
|
@@ -417,6 +513,24 @@ class WorkbookItem:
|
|
|
417
513
|
self.data_acceleration_config = data_acceleration_config
|
|
418
514
|
if data_freshness_policy is not None:
|
|
419
515
|
self.data_freshness_policy = data_freshness_policy
|
|
516
|
+
if sheet_count is not None:
|
|
517
|
+
self._sheet_count = sheet_count
|
|
518
|
+
if has_extracts is not None:
|
|
519
|
+
self._has_extracts = has_extracts
|
|
520
|
+
if project:
|
|
521
|
+
self._project = project
|
|
522
|
+
if owner:
|
|
523
|
+
self._owner = owner
|
|
524
|
+
if location:
|
|
525
|
+
self._location = location
|
|
526
|
+
if encrypt_extracts is not None:
|
|
527
|
+
self._encrypt_extracts = encrypt_extracts
|
|
528
|
+
if default_view_id is not None:
|
|
529
|
+
self._default_view_id = default_view_id
|
|
530
|
+
if share_description is not None:
|
|
531
|
+
self._share_description = share_description
|
|
532
|
+
if last_published_at is not None:
|
|
533
|
+
self._last_published_at = last_published_at
|
|
420
534
|
|
|
421
535
|
@classmethod
|
|
422
536
|
def from_response(cls, resp: str, ns: dict[str, str]) -> list["WorkbookItem"]:
|
|
@@ -443,6 +557,12 @@ class WorkbookItem:
|
|
|
443
557
|
created_at = parse_datetime(workbook_xml.get("createdAt", None))
|
|
444
558
|
description = workbook_xml.get("description", None)
|
|
445
559
|
updated_at = parse_datetime(workbook_xml.get("updatedAt", None))
|
|
560
|
+
sheet_count = string_to_int(workbook_xml.get("sheetCount", None))
|
|
561
|
+
has_extracts = string_to_bool(workbook_xml.get("hasExtracts", ""))
|
|
562
|
+
encrypt_extracts = string_to_bool(e) if (e := workbook_xml.get("encryptExtracts", None)) is not None else None
|
|
563
|
+
default_view_id = workbook_xml.get("defaultViewId", None)
|
|
564
|
+
share_description = workbook_xml.get("shareDescription", None)
|
|
565
|
+
last_published_at = parse_datetime(workbook_xml.get("lastPublishedAt", None))
|
|
446
566
|
|
|
447
567
|
size = workbook_xml.get("size", None)
|
|
448
568
|
if size:
|
|
@@ -452,14 +572,18 @@ class WorkbookItem:
|
|
|
452
572
|
|
|
453
573
|
project_id = None
|
|
454
574
|
project_name = None
|
|
575
|
+
project = None
|
|
455
576
|
project_tag = workbook_xml.find(".//t:project", namespaces=ns)
|
|
456
577
|
if project_tag is not None:
|
|
578
|
+
project = ProjectItem.from_xml(project_tag, ns)
|
|
457
579
|
project_id = project_tag.get("id", None)
|
|
458
580
|
project_name = project_tag.get("name", None)
|
|
459
581
|
|
|
460
582
|
owner_id = None
|
|
583
|
+
owner = None
|
|
461
584
|
owner_tag = workbook_xml.find(".//t:owner", namespaces=ns)
|
|
462
585
|
if owner_tag is not None:
|
|
586
|
+
owner = UserItem.from_xml(owner_tag, ns)
|
|
463
587
|
owner_id = owner_tag.get("id", None)
|
|
464
588
|
|
|
465
589
|
tags = None
|
|
@@ -473,6 +597,11 @@ class WorkbookItem:
|
|
|
473
597
|
if views_elem is not None:
|
|
474
598
|
views = ViewItem.from_xml_element(views_elem, ns)
|
|
475
599
|
|
|
600
|
+
location = None
|
|
601
|
+
location_elem = workbook_xml.find(".//t:location", namespaces=ns)
|
|
602
|
+
if location_elem is not None:
|
|
603
|
+
location = LocationItem.from_xml(location_elem, ns)
|
|
604
|
+
|
|
476
605
|
data_acceleration_config = {
|
|
477
606
|
"acceleration_enabled": None,
|
|
478
607
|
"accelerate_now": None,
|
|
@@ -505,6 +634,15 @@ class WorkbookItem:
|
|
|
505
634
|
views,
|
|
506
635
|
data_acceleration_config,
|
|
507
636
|
data_freshness_policy,
|
|
637
|
+
sheet_count,
|
|
638
|
+
has_extracts,
|
|
639
|
+
project,
|
|
640
|
+
owner,
|
|
641
|
+
location,
|
|
642
|
+
encrypt_extracts,
|
|
643
|
+
default_view_id,
|
|
644
|
+
share_description,
|
|
645
|
+
last_published_at,
|
|
508
646
|
)
|
|
509
647
|
|
|
510
648
|
|
|
@@ -535,3 +673,15 @@ def parse_data_acceleration_config(data_acceleration_elem):
|
|
|
535
673
|
# Used to convert string represented boolean to a boolean type
|
|
536
674
|
def string_to_bool(s: str) -> bool:
|
|
537
675
|
return s.lower() == "true"
|
|
676
|
+
|
|
677
|
+
|
|
678
|
+
@overload
|
|
679
|
+
def string_to_int(s: None) -> None: ...
|
|
680
|
+
|
|
681
|
+
|
|
682
|
+
@overload
|
|
683
|
+
def string_to_int(s: str) -> int: ...
|
|
684
|
+
|
|
685
|
+
|
|
686
|
+
def string_to_int(s):
|
|
687
|
+
return int(s) if s is not None else None
|
|
@@ -5,6 +5,7 @@ from tableauserverclient.server.request_options import (
|
|
|
5
5
|
ExcelRequestOptions,
|
|
6
6
|
ImageRequestOptions,
|
|
7
7
|
PDFRequestOptions,
|
|
8
|
+
PPTXRequestOptions,
|
|
8
9
|
RequestOptions,
|
|
9
10
|
)
|
|
10
11
|
from tableauserverclient.server.filter import Filter
|
|
@@ -52,6 +53,7 @@ __all__ = [
|
|
|
52
53
|
"ExcelRequestOptions",
|
|
53
54
|
"ImageRequestOptions",
|
|
54
55
|
"PDFRequestOptions",
|
|
56
|
+
"PPTXRequestOptions",
|
|
55
57
|
"RequestOptions",
|
|
56
58
|
"Filter",
|
|
57
59
|
"Sort",
|