tableauserverclient 0.37__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.
- tableauserverclient/bin/_version.py → _version.py +3 -3
- bin/__init__.py +3 -0
- bin/_version.py +21 -0
- {tableauserverclient/helpers → helpers}/strings.py +25 -1
- {tableauserverclient/models → models}/__init__.py +15 -1
- models/collection_item.py +52 -0
- {tableauserverclient/models → models}/connection_item.py +16 -2
- {tableauserverclient/models → models}/custom_view_item.py +8 -0
- {tableauserverclient/models → models}/data_freshness_policy_item.py +3 -3
- {tableauserverclient/models → models}/datasource_item.py +113 -3
- models/extensions_item.py +186 -0
- models/extract_item.py +82 -0
- {tableauserverclient/models → models}/favorites_item.py +21 -8
- {tableauserverclient/models → models}/flow_item.py +3 -3
- {tableauserverclient/models → models}/group_item.py +18 -1
- {tableauserverclient/models → models}/groupset_item.py +14 -0
- {tableauserverclient/models → models}/interval_item.py +42 -1
- models/location_item.py +53 -0
- models/oidc_item.py +82 -0
- {tableauserverclient/models → models}/permissions_item.py +2 -0
- {tableauserverclient/models → models}/project_item.py +141 -29
- {tableauserverclient/models → models}/property_decorators.py +2 -2
- {tableauserverclient/models → models}/reference_item.py +12 -6
- {tableauserverclient/models → models}/schedule_item.py +67 -1
- {tableauserverclient/models → models}/site_item.py +54 -0
- {tableauserverclient/models → models}/table_item.py +7 -3
- {tableauserverclient/models → models}/tableau_auth.py +13 -6
- {tableauserverclient/models → models}/tableau_types.py +13 -1
- {tableauserverclient/models → models}/user_item.py +111 -4
- {tableauserverclient/models → models}/view_item.py +79 -5
- {tableauserverclient/models → models}/workbook_item.py +153 -3
- {tableauserverclient/server → server}/endpoint/__init__.py +4 -0
- {tableauserverclient/server → server}/endpoint/databases_endpoint.py +101 -18
- {tableauserverclient/server → server}/endpoint/datasources_endpoint.py +155 -25
- {tableauserverclient/server → server}/endpoint/dqw_endpoint.py +16 -6
- {tableauserverclient/server → server}/endpoint/endpoint.py +39 -0
- server/endpoint/extensions_endpoint.py +79 -0
- {tableauserverclient/server → server}/endpoint/flow_task_endpoint.py +1 -1
- {tableauserverclient/server → server}/endpoint/flows_endpoint.py +5 -4
- server/endpoint/oidc_endpoint.py +157 -0
- {tableauserverclient/server → server}/endpoint/projects_endpoint.py +12 -0
- server/endpoint/schedules_endpoint.py +328 -0
- {tableauserverclient/server → server}/endpoint/sites_endpoint.py +18 -1
- {tableauserverclient/server → server}/endpoint/tables_endpoint.py +140 -17
- {tableauserverclient/server → server}/endpoint/users_endpoint.py +296 -10
- {tableauserverclient/server → server}/endpoint/views_endpoint.py +23 -0
- {tableauserverclient/server → server}/endpoint/workbooks_endpoint.py +124 -9
- {tableauserverclient/server → server}/query.py +36 -0
- {tableauserverclient/server → server}/request_factory.py +286 -2
- {tableauserverclient/server → server}/request_options.py +139 -3
- {tableauserverclient/server → server}/server.py +46 -0
- {tableauserverclient-0.37.dist-info → tableauserverclient-0.39.dist-info}/METADATA +5 -26
- tableauserverclient-0.39.dist-info/RECORD +107 -0
- {tableauserverclient-0.37.dist-info → tableauserverclient-0.39.dist-info}/WHEEL +1 -1
- tableauserverclient-0.39.dist-info/top_level.txt +4 -0
- tableauserverclient/__init__.py +0 -141
- tableauserverclient/config.py +0 -27
- tableauserverclient/datetime_helpers.py +0 -45
- tableauserverclient/exponential_backoff.py +0 -30
- tableauserverclient/filesys_helpers.py +0 -63
- tableauserverclient/namespace.py +0 -37
- tableauserverclient/py.typed +0 -0
- tableauserverclient/server/endpoint/schedules_endpoint.py +0 -151
- tableauserverclient-0.37.dist-info/RECORD +0 -106
- tableauserverclient-0.37.dist-info/licenses/LICENSE.versioneer +0 -7
- tableauserverclient-0.37.dist-info/top_level.txt +0 -1
- {tableauserverclient/helpers → helpers}/__init__.py +0 -0
- {tableauserverclient/helpers → helpers}/headers.py +0 -0
- {tableauserverclient/helpers → helpers}/logging.py +0 -0
- {tableauserverclient/models → models}/column_item.py +0 -0
- {tableauserverclient/models → models}/connection_credentials.py +0 -0
- {tableauserverclient/models → models}/data_acceleration_report_item.py +0 -0
- {tableauserverclient/models → models}/data_alert_item.py +0 -0
- {tableauserverclient/models → models}/database_item.py +0 -0
- {tableauserverclient/models → models}/dqw_item.py +0 -0
- {tableauserverclient/models → models}/exceptions.py +0 -0
- {tableauserverclient/models → models}/fileupload_item.py +0 -0
- {tableauserverclient/models → models}/flow_run_item.py +0 -0
- {tableauserverclient/models → models}/job_item.py +0 -0
- {tableauserverclient/models → models}/linked_tasks_item.py +0 -0
- {tableauserverclient/models → models}/metric_item.py +0 -0
- {tableauserverclient/models → models}/pagination_item.py +0 -0
- {tableauserverclient/models → models}/revision_item.py +0 -0
- {tableauserverclient/models → models}/server_info_item.py +0 -0
- {tableauserverclient/models → models}/subscription_item.py +0 -0
- {tableauserverclient/models → models}/tag_item.py +0 -0
- {tableauserverclient/models → models}/target.py +0 -0
- {tableauserverclient/models → models}/task_item.py +0 -0
- {tableauserverclient/models → models}/virtual_connection_item.py +0 -0
- {tableauserverclient/models → models}/webhook_item.py +0 -0
- {tableauserverclient/server → server}/__init__.py +0 -0
- {tableauserverclient/server → server}/endpoint/auth_endpoint.py +0 -0
- {tableauserverclient/server → server}/endpoint/custom_views_endpoint.py +0 -0
- {tableauserverclient/server → server}/endpoint/data_acceleration_report_endpoint.py +0 -0
- {tableauserverclient/server → server}/endpoint/data_alert_endpoint.py +0 -0
- {tableauserverclient/server → server}/endpoint/default_permissions_endpoint.py +0 -0
- {tableauserverclient/server → server}/endpoint/exceptions.py +0 -0
- {tableauserverclient/server → server}/endpoint/favorites_endpoint.py +0 -0
- {tableauserverclient/server → server}/endpoint/fileuploads_endpoint.py +0 -0
- {tableauserverclient/server → server}/endpoint/flow_runs_endpoint.py +0 -0
- {tableauserverclient/server → server}/endpoint/groups_endpoint.py +0 -0
- {tableauserverclient/server → server}/endpoint/groupsets_endpoint.py +0 -0
- {tableauserverclient/server → server}/endpoint/jobs_endpoint.py +0 -0
- {tableauserverclient/server → server}/endpoint/linked_tasks_endpoint.py +0 -0
- {tableauserverclient/server → server}/endpoint/metadata_endpoint.py +0 -0
- {tableauserverclient/server → server}/endpoint/metrics_endpoint.py +0 -0
- {tableauserverclient/server → server}/endpoint/permissions_endpoint.py +0 -0
- {tableauserverclient/server → server}/endpoint/resource_tagger.py +0 -0
- {tableauserverclient/server → server}/endpoint/server_info_endpoint.py +0 -0
- {tableauserverclient/server → server}/endpoint/subscriptions_endpoint.py +0 -0
- {tableauserverclient/server → server}/endpoint/tasks_endpoint.py +0 -0
- {tableauserverclient/server → server}/endpoint/virtual_connections_endpoint.py +0 -0
- {tableauserverclient/server → server}/endpoint/webhooks_endpoint.py +0 -0
- {tableauserverclient/server → server}/exceptions.py +0 -0
- {tableauserverclient/server → server}/filter.py +0 -0
- {tableauserverclient/server → server}/pager.py +0 -0
- {tableauserverclient/server → server}/sort.py +0 -0
- {tableauserverclient-0.37.dist-info → tableauserverclient-0.39.dist-info}/licenses/LICENSE +0 -0
|
@@ -5,8 +5,10 @@ from enum import IntEnum
|
|
|
5
5
|
from typing import Optional, TYPE_CHECKING
|
|
6
6
|
|
|
7
7
|
from defusedxml.ElementTree import fromstring
|
|
8
|
+
from typing_extensions import Self
|
|
8
9
|
|
|
9
10
|
from tableauserverclient.datetime_helpers import parse_datetime
|
|
11
|
+
from tableauserverclient.models.site_item import SiteAuthConfiguration
|
|
10
12
|
from .exceptions import UnpopulatedPropertyError
|
|
11
13
|
from .property_decorators import (
|
|
12
14
|
property_is_enum,
|
|
@@ -16,6 +18,7 @@ from .reference_item import ResourceReference
|
|
|
16
18
|
|
|
17
19
|
if TYPE_CHECKING:
|
|
18
20
|
from tableauserverclient.server import Pager
|
|
21
|
+
from tableauserverclient.models.favorites_item import FavoriteType
|
|
19
22
|
|
|
20
23
|
|
|
21
24
|
class UserItem:
|
|
@@ -37,6 +40,49 @@ class UserItem:
|
|
|
37
40
|
auth_setting: str
|
|
38
41
|
Required attribute for Tableau Cloud. How the user autenticates to the
|
|
39
42
|
server.
|
|
43
|
+
|
|
44
|
+
Attributes
|
|
45
|
+
----------
|
|
46
|
+
domain_name: Optional[str]
|
|
47
|
+
The name of the Active Directory domain ("local" if local authentication
|
|
48
|
+
is used).
|
|
49
|
+
|
|
50
|
+
email: Optional[str]
|
|
51
|
+
The email address of the user.
|
|
52
|
+
|
|
53
|
+
external_auth_user_id: Optional[str]
|
|
54
|
+
The unique identifier for the user in the external authentication system.
|
|
55
|
+
|
|
56
|
+
id: Optional[str]
|
|
57
|
+
The unique identifier for the user.
|
|
58
|
+
|
|
59
|
+
favorites: dict[str, list]
|
|
60
|
+
The favorites of the user. Must be populated with a call to
|
|
61
|
+
`populate_favorites()`.
|
|
62
|
+
|
|
63
|
+
fullname: Optional[str]
|
|
64
|
+
The full name of the user.
|
|
65
|
+
|
|
66
|
+
groups: Pager
|
|
67
|
+
The groups the user belongs to. Must be populated with a call to
|
|
68
|
+
`populate_groups()`.
|
|
69
|
+
|
|
70
|
+
last_login: Optional[datetime]
|
|
71
|
+
The last time the user logged in.
|
|
72
|
+
|
|
73
|
+
locale: Optional[str]
|
|
74
|
+
The locale of the user.
|
|
75
|
+
|
|
76
|
+
language: Optional[str]
|
|
77
|
+
Language setting for the user.
|
|
78
|
+
|
|
79
|
+
idp_configuration_id: Optional[str]
|
|
80
|
+
The ID of the identity provider configuration.
|
|
81
|
+
|
|
82
|
+
workbooks: Pager
|
|
83
|
+
The workbooks owned by the user. Must be populated with a call to
|
|
84
|
+
`populate_workbooks()`.
|
|
85
|
+
|
|
40
86
|
"""
|
|
41
87
|
|
|
42
88
|
tag_name: str = "user"
|
|
@@ -87,13 +133,16 @@ class UserItem:
|
|
|
87
133
|
self._id: Optional[str] = None
|
|
88
134
|
self._last_login: Optional[datetime] = None
|
|
89
135
|
self._workbooks = None
|
|
90
|
-
self._favorites: Optional[
|
|
136
|
+
self._favorites: Optional["FavoriteType"] = None
|
|
91
137
|
self._groups = None
|
|
92
138
|
self.email: Optional[str] = None
|
|
93
139
|
self.fullname: Optional[str] = None
|
|
94
140
|
self.name: Optional[str] = name
|
|
95
141
|
self.site_role: Optional[str] = site_role
|
|
96
142
|
self.auth_setting: Optional[str] = auth_setting
|
|
143
|
+
self._locale: Optional[str] = None
|
|
144
|
+
self._language: Optional[str] = None
|
|
145
|
+
self._idp_configuration_id: Optional[str] = None
|
|
97
146
|
|
|
98
147
|
return None
|
|
99
148
|
|
|
@@ -138,7 +187,7 @@ class UserItem:
|
|
|
138
187
|
return self._name
|
|
139
188
|
|
|
140
189
|
@name.setter
|
|
141
|
-
def name(self, value: str):
|
|
190
|
+
def name(self, value: Optional[str]):
|
|
142
191
|
self._name = value
|
|
143
192
|
|
|
144
193
|
# valid: username, domain/username, username@domain, domain/username@email
|
|
@@ -171,7 +220,7 @@ class UserItem:
|
|
|
171
220
|
return self._workbooks()
|
|
172
221
|
|
|
173
222
|
@property
|
|
174
|
-
def favorites(self) ->
|
|
223
|
+
def favorites(self) -> "FavoriteType":
|
|
175
224
|
if self._favorites is None:
|
|
176
225
|
error = "User item must be populated with favorites first."
|
|
177
226
|
raise UnpopulatedPropertyError(error)
|
|
@@ -184,6 +233,26 @@ class UserItem:
|
|
|
184
233
|
raise UnpopulatedPropertyError(error)
|
|
185
234
|
return self._groups()
|
|
186
235
|
|
|
236
|
+
@property
|
|
237
|
+
def locale(self) -> Optional[str]:
|
|
238
|
+
return self._locale
|
|
239
|
+
|
|
240
|
+
@property
|
|
241
|
+
def language(self) -> Optional[str]:
|
|
242
|
+
return self._language
|
|
243
|
+
|
|
244
|
+
@property
|
|
245
|
+
def idp_configuration_id(self) -> Optional[str]:
|
|
246
|
+
"""
|
|
247
|
+
IDP configuration id for the user. This is only available on Tableau
|
|
248
|
+
Cloud, 3.24 or later
|
|
249
|
+
"""
|
|
250
|
+
return self._idp_configuration_id
|
|
251
|
+
|
|
252
|
+
@idp_configuration_id.setter
|
|
253
|
+
def idp_configuration_id(self, value: str) -> None:
|
|
254
|
+
self._idp_configuration_id = value
|
|
255
|
+
|
|
187
256
|
def _set_workbooks(self, workbooks) -> None:
|
|
188
257
|
self._workbooks = workbooks
|
|
189
258
|
|
|
@@ -204,8 +273,11 @@ class UserItem:
|
|
|
204
273
|
email,
|
|
205
274
|
auth_setting,
|
|
206
275
|
_,
|
|
276
|
+
_,
|
|
277
|
+
_,
|
|
278
|
+
_,
|
|
207
279
|
) = self._parse_element(user_xml, ns)
|
|
208
|
-
self._set_values(None, None, site_role, None, None, fullname, email, auth_setting, None)
|
|
280
|
+
self._set_values(None, None, site_role, None, None, fullname, email, auth_setting, None, None, None, None)
|
|
209
281
|
return self
|
|
210
282
|
|
|
211
283
|
def _set_values(
|
|
@@ -219,6 +291,9 @@ class UserItem:
|
|
|
219
291
|
email,
|
|
220
292
|
auth_setting,
|
|
221
293
|
domain_name,
|
|
294
|
+
locale,
|
|
295
|
+
language,
|
|
296
|
+
idp_configuration_id,
|
|
222
297
|
):
|
|
223
298
|
if id is not None:
|
|
224
299
|
self._id = id
|
|
@@ -238,6 +313,12 @@ class UserItem:
|
|
|
238
313
|
self._auth_setting = auth_setting
|
|
239
314
|
if domain_name:
|
|
240
315
|
self._domain_name = domain_name
|
|
316
|
+
if locale:
|
|
317
|
+
self._locale = locale
|
|
318
|
+
if language:
|
|
319
|
+
self._language = language
|
|
320
|
+
if idp_configuration_id:
|
|
321
|
+
self._idp_configuration_id = idp_configuration_id
|
|
241
322
|
|
|
242
323
|
@classmethod
|
|
243
324
|
def from_response(cls, resp, ns) -> list["UserItem"]:
|
|
@@ -249,6 +330,12 @@ class UserItem:
|
|
|
249
330
|
element_name = ".//t:owner"
|
|
250
331
|
return cls._parse_xml(element_name, resp, ns)
|
|
251
332
|
|
|
333
|
+
@classmethod
|
|
334
|
+
def from_xml(cls, xml: ET.Element, ns: Optional[dict] = None) -> "UserItem":
|
|
335
|
+
item = cls()
|
|
336
|
+
item._set_values(*cls._parse_element(xml, ns))
|
|
337
|
+
return item
|
|
338
|
+
|
|
252
339
|
@classmethod
|
|
253
340
|
def _parse_xml(cls, element_name, resp, ns):
|
|
254
341
|
all_user_items = []
|
|
@@ -265,6 +352,9 @@ class UserItem:
|
|
|
265
352
|
email,
|
|
266
353
|
auth_setting,
|
|
267
354
|
domain_name,
|
|
355
|
+
locale,
|
|
356
|
+
language,
|
|
357
|
+
idp_configuration_id,
|
|
268
358
|
) = cls._parse_element(user_xml, ns)
|
|
269
359
|
user_item = cls(name, site_role)
|
|
270
360
|
user_item._set_values(
|
|
@@ -277,6 +367,9 @@ class UserItem:
|
|
|
277
367
|
email,
|
|
278
368
|
auth_setting,
|
|
279
369
|
domain_name,
|
|
370
|
+
locale,
|
|
371
|
+
language,
|
|
372
|
+
idp_configuration_id,
|
|
280
373
|
)
|
|
281
374
|
all_user_items.append(user_item)
|
|
282
375
|
return all_user_items
|
|
@@ -285,6 +378,11 @@ class UserItem:
|
|
|
285
378
|
def as_reference(id_) -> ResourceReference:
|
|
286
379
|
return ResourceReference(id_, UserItem.tag_name)
|
|
287
380
|
|
|
381
|
+
def to_reference(self: Self) -> ResourceReference:
|
|
382
|
+
if self.id is None:
|
|
383
|
+
raise ValueError(f"{self.__class__.__qualname__} must have id to be converted to reference")
|
|
384
|
+
return ResourceReference(self.id, self.tag_name)
|
|
385
|
+
|
|
288
386
|
@staticmethod
|
|
289
387
|
def _parse_element(user_xml, ns):
|
|
290
388
|
id = user_xml.get("id", None)
|
|
@@ -295,6 +393,9 @@ class UserItem:
|
|
|
295
393
|
fullname = user_xml.get("fullName", None)
|
|
296
394
|
email = user_xml.get("email", None)
|
|
297
395
|
auth_setting = user_xml.get("authSetting", None)
|
|
396
|
+
locale = user_xml.get("locale", None)
|
|
397
|
+
language = user_xml.get("language", None)
|
|
398
|
+
idp_configuration_id = user_xml.get("idpConfigurationId", None)
|
|
298
399
|
|
|
299
400
|
domain_name = None
|
|
300
401
|
domain_elem = user_xml.find(".//t:domain", namespaces=ns)
|
|
@@ -311,6 +412,9 @@ class UserItem:
|
|
|
311
412
|
email,
|
|
312
413
|
auth_setting,
|
|
313
414
|
domain_name,
|
|
415
|
+
locale,
|
|
416
|
+
language,
|
|
417
|
+
idp_configuration_id,
|
|
314
418
|
)
|
|
315
419
|
|
|
316
420
|
class CSVImport:
|
|
@@ -361,6 +465,9 @@ class UserItem:
|
|
|
361
465
|
values[UserItem.CSVImport.ColumnType.EMAIL],
|
|
362
466
|
values[UserItem.CSVImport.ColumnType.AUTH],
|
|
363
467
|
None,
|
|
468
|
+
None,
|
|
469
|
+
None,
|
|
470
|
+
None,
|
|
364
471
|
)
|
|
365
472
|
return user
|
|
366
473
|
|
|
@@ -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
|
|
@@ -289,7 +330,7 @@ class WorkbookItem:
|
|
|
289
330
|
return self._thumbnails_user_id
|
|
290
331
|
|
|
291
332
|
@thumbnails_user_id.setter
|
|
292
|
-
def thumbnails_user_id(self, value: str):
|
|
333
|
+
def thumbnails_user_id(self, value: Optional[str]):
|
|
293
334
|
self._thumbnails_user_id = value
|
|
294
335
|
|
|
295
336
|
@property
|
|
@@ -297,9 +338,37 @@ class WorkbookItem:
|
|
|
297
338
|
return self._thumbnails_group_id
|
|
298
339
|
|
|
299
340
|
@thumbnails_group_id.setter
|
|
300
|
-
def thumbnails_group_id(self, value: str):
|
|
341
|
+
def thumbnails_group_id(self, value: Optional[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
|