tableauserverclient 0.30.post0.dev1__py3-none-any.whl → 0.32__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 +64 -4
- tableauserverclient/_version.py +3 -3
- tableauserverclient/models/__init__.py +88 -37
- tableauserverclient/models/datasource_item.py +18 -6
- tableauserverclient/models/favorites_item.py +7 -7
- tableauserverclient/models/permissions_item.py +46 -1
- tableauserverclient/models/project_item.py +4 -3
- tableauserverclient/models/reference_item.py +5 -0
- tableauserverclient/models/tableau_auth.py +22 -23
- tableauserverclient/server/__init__.py +83 -8
- tableauserverclient/server/endpoint/__init__.py +61 -28
- tableauserverclient/server/endpoint/custom_views_endpoint.py +1 -1
- tableauserverclient/server/endpoint/databases_endpoint.py +0 -11
- tableauserverclient/server/endpoint/datasources_endpoint.py +12 -28
- tableauserverclient/server/endpoint/endpoint.py +23 -8
- tableauserverclient/server/endpoint/favorites_endpoint.py +1 -1
- tableauserverclient/server/endpoint/flow_runs_endpoint.py +1 -1
- tableauserverclient/server/endpoint/flows_endpoint.py +1 -11
- tableauserverclient/server/endpoint/groups_endpoint.py +3 -17
- tableauserverclient/server/endpoint/jobs_endpoint.py +1 -1
- tableauserverclient/server/endpoint/metadata_endpoint.py +3 -3
- tableauserverclient/server/endpoint/metrics_endpoint.py +1 -1
- tableauserverclient/server/endpoint/projects_endpoint.py +7 -18
- tableauserverclient/server/endpoint/tables_endpoint.py +0 -10
- tableauserverclient/server/endpoint/users_endpoint.py +1 -1
- tableauserverclient/server/endpoint/views_endpoint.py +4 -2
- tableauserverclient/server/endpoint/workbooks_endpoint.py +7 -36
- tableauserverclient/server/pager.py +47 -46
- tableauserverclient/server/query.py +61 -33
- tableauserverclient/server/request_factory.py +14 -42
- tableauserverclient/server/server.py +5 -6
- {tableauserverclient-0.30.post0.dev1.dist-info → tableauserverclient-0.32.dist-info}/METADATA +3 -4
- {tableauserverclient-0.30.post0.dev1.dist-info → tableauserverclient-0.32.dist-info}/RECORD +37 -37
- {tableauserverclient-0.30.post0.dev1.dist-info → tableauserverclient-0.32.dist-info}/WHEEL +1 -1
- {tableauserverclient-0.30.post0.dev1.dist-info → tableauserverclient-0.32.dist-info}/LICENSE +0 -0
- {tableauserverclient-0.30.post0.dev1.dist-info → tableauserverclient-0.32.dist-info}/LICENSE.versioneer +0 -0
- {tableauserverclient-0.30.post0.dev1.dist-info → tableauserverclient-0.32.dist-info}/top_level.txt +0 -0
|
@@ -1,28 +1,61 @@
|
|
|
1
|
-
from .auth_endpoint import Auth
|
|
2
|
-
from .custom_views_endpoint import CustomViews
|
|
3
|
-
from .data_acceleration_report_endpoint import DataAccelerationReport
|
|
4
|
-
from .data_alert_endpoint import DataAlerts
|
|
5
|
-
from .databases_endpoint import Databases
|
|
6
|
-
from .datasources_endpoint import Datasources
|
|
7
|
-
from .endpoint import Endpoint, QuerysetEndpoint
|
|
8
|
-
from .exceptions import ServerResponseError, MissingRequiredFieldError
|
|
9
|
-
from .favorites_endpoint import Favorites
|
|
10
|
-
from .fileuploads_endpoint import Fileuploads
|
|
11
|
-
from .flow_runs_endpoint import FlowRuns
|
|
12
|
-
from .flows_endpoint import Flows
|
|
13
|
-
from .flow_task_endpoint import FlowTasks
|
|
14
|
-
from .groups_endpoint import Groups
|
|
15
|
-
from .jobs_endpoint import Jobs
|
|
16
|
-
from .metadata_endpoint import Metadata
|
|
17
|
-
from .metrics_endpoint import Metrics
|
|
18
|
-
from .projects_endpoint import Projects
|
|
19
|
-
from .schedules_endpoint import Schedules
|
|
20
|
-
from .server_info_endpoint import ServerInfo
|
|
21
|
-
from .sites_endpoint import Sites
|
|
22
|
-
from .subscriptions_endpoint import Subscriptions
|
|
23
|
-
from .tables_endpoint import Tables
|
|
24
|
-
from .tasks_endpoint import Tasks
|
|
25
|
-
from .users_endpoint import Users
|
|
26
|
-
from .views_endpoint import Views
|
|
27
|
-
from .webhooks_endpoint import Webhooks
|
|
28
|
-
from .workbooks_endpoint import Workbooks
|
|
1
|
+
from tableauserverclient.server.endpoint.auth_endpoint import Auth
|
|
2
|
+
from tableauserverclient.server.endpoint.custom_views_endpoint import CustomViews
|
|
3
|
+
from tableauserverclient.server.endpoint.data_acceleration_report_endpoint import DataAccelerationReport
|
|
4
|
+
from tableauserverclient.server.endpoint.data_alert_endpoint import DataAlerts
|
|
5
|
+
from tableauserverclient.server.endpoint.databases_endpoint import Databases
|
|
6
|
+
from tableauserverclient.server.endpoint.datasources_endpoint import Datasources
|
|
7
|
+
from tableauserverclient.server.endpoint.endpoint import Endpoint, QuerysetEndpoint
|
|
8
|
+
from tableauserverclient.server.endpoint.exceptions import ServerResponseError, MissingRequiredFieldError
|
|
9
|
+
from tableauserverclient.server.endpoint.favorites_endpoint import Favorites
|
|
10
|
+
from tableauserverclient.server.endpoint.fileuploads_endpoint import Fileuploads
|
|
11
|
+
from tableauserverclient.server.endpoint.flow_runs_endpoint import FlowRuns
|
|
12
|
+
from tableauserverclient.server.endpoint.flows_endpoint import Flows
|
|
13
|
+
from tableauserverclient.server.endpoint.flow_task_endpoint import FlowTasks
|
|
14
|
+
from tableauserverclient.server.endpoint.groups_endpoint import Groups
|
|
15
|
+
from tableauserverclient.server.endpoint.jobs_endpoint import Jobs
|
|
16
|
+
from tableauserverclient.server.endpoint.metadata_endpoint import Metadata
|
|
17
|
+
from tableauserverclient.server.endpoint.metrics_endpoint import Metrics
|
|
18
|
+
from tableauserverclient.server.endpoint.projects_endpoint import Projects
|
|
19
|
+
from tableauserverclient.server.endpoint.schedules_endpoint import Schedules
|
|
20
|
+
from tableauserverclient.server.endpoint.server_info_endpoint import ServerInfo
|
|
21
|
+
from tableauserverclient.server.endpoint.sites_endpoint import Sites
|
|
22
|
+
from tableauserverclient.server.endpoint.subscriptions_endpoint import Subscriptions
|
|
23
|
+
from tableauserverclient.server.endpoint.tables_endpoint import Tables
|
|
24
|
+
from tableauserverclient.server.endpoint.tasks_endpoint import Tasks
|
|
25
|
+
from tableauserverclient.server.endpoint.users_endpoint import Users
|
|
26
|
+
from tableauserverclient.server.endpoint.views_endpoint import Views
|
|
27
|
+
from tableauserverclient.server.endpoint.webhooks_endpoint import Webhooks
|
|
28
|
+
from tableauserverclient.server.endpoint.workbooks_endpoint import Workbooks
|
|
29
|
+
|
|
30
|
+
__all__ = [
|
|
31
|
+
"Auth",
|
|
32
|
+
"CustomViews",
|
|
33
|
+
"DataAccelerationReport",
|
|
34
|
+
"DataAlerts",
|
|
35
|
+
"Databases",
|
|
36
|
+
"Datasources",
|
|
37
|
+
"QuerysetEndpoint",
|
|
38
|
+
"MissingRequiredFieldError",
|
|
39
|
+
"Endpoint",
|
|
40
|
+
"Favorites",
|
|
41
|
+
"Fileuploads",
|
|
42
|
+
"FlowRuns",
|
|
43
|
+
"Flows",
|
|
44
|
+
"FlowTasks",
|
|
45
|
+
"Groups",
|
|
46
|
+
"Jobs",
|
|
47
|
+
"Metadata",
|
|
48
|
+
"Metrics",
|
|
49
|
+
"Projects",
|
|
50
|
+
"Schedules",
|
|
51
|
+
"ServerInfo",
|
|
52
|
+
"ServerResponseError",
|
|
53
|
+
"Sites",
|
|
54
|
+
"Subscriptions",
|
|
55
|
+
"Tables",
|
|
56
|
+
"Tasks",
|
|
57
|
+
"Users",
|
|
58
|
+
"Views",
|
|
59
|
+
"Webhooks",
|
|
60
|
+
"Workbooks",
|
|
61
|
+
]
|
|
@@ -88,17 +88,6 @@ class Databases(Endpoint):
|
|
|
88
88
|
def populate_permissions(self, item):
|
|
89
89
|
self._permissions.populate(item)
|
|
90
90
|
|
|
91
|
-
@api(version="3.5")
|
|
92
|
-
def update_permission(self, item, rules):
|
|
93
|
-
import warnings
|
|
94
|
-
|
|
95
|
-
warnings.warn(
|
|
96
|
-
"Server.databases.update_permission is deprecated, "
|
|
97
|
-
"please use Server.databases.update_permissions instead.",
|
|
98
|
-
DeprecationWarning,
|
|
99
|
-
)
|
|
100
|
-
return self._permissions.update(item, rules)
|
|
101
|
-
|
|
102
91
|
@api(version="3.5")
|
|
103
92
|
def update_permissions(self, item, rules):
|
|
104
93
|
return self._permissions.update(item, rules)
|
|
@@ -15,11 +15,11 @@ if TYPE_CHECKING:
|
|
|
15
15
|
from tableauserverclient.models import PermissionsRule
|
|
16
16
|
from .schedules_endpoint import AddResponse
|
|
17
17
|
|
|
18
|
-
from .dqw_endpoint import _DataQualityWarningEndpoint
|
|
19
|
-
from .endpoint import QuerysetEndpoint, api, parameter_added_in
|
|
20
|
-
from .exceptions import InternalServerError, MissingRequiredFieldError
|
|
21
|
-
from .permissions_endpoint import _PermissionsEndpoint
|
|
22
|
-
from .resource_tagger import _ResourceTagger
|
|
18
|
+
from tableauserverclient.server.endpoint.dqw_endpoint import _DataQualityWarningEndpoint
|
|
19
|
+
from tableauserverclient.server.endpoint.endpoint import QuerysetEndpoint, api, parameter_added_in
|
|
20
|
+
from tableauserverclient.server.endpoint.exceptions import InternalServerError, MissingRequiredFieldError
|
|
21
|
+
from tableauserverclient.server.endpoint.permissions_endpoint import _PermissionsEndpoint
|
|
22
|
+
from tableauserverclient.server.endpoint.resource_tagger import _ResourceTagger
|
|
23
23
|
|
|
24
24
|
from tableauserverclient.config import ALLOWED_FILE_EXTENSIONS, FILESIZE_LIMIT_MB, BYTES_PER_MB, CHUNK_SIZE_MB
|
|
25
25
|
from tableauserverclient.filesys_helpers import (
|
|
@@ -54,7 +54,7 @@ PathOrFileR = Union[FilePath, FileObjectR]
|
|
|
54
54
|
PathOrFileW = Union[FilePath, FileObjectW]
|
|
55
55
|
|
|
56
56
|
|
|
57
|
-
class Datasources(QuerysetEndpoint):
|
|
57
|
+
class Datasources(QuerysetEndpoint[DatasourceItem]):
|
|
58
58
|
def __init__(self, parent_srv: "Server") -> None:
|
|
59
59
|
super(Datasources, self).__init__(parent_srv)
|
|
60
60
|
self._resource_tagger = _ResourceTagger(parent_srv)
|
|
@@ -126,9 +126,13 @@ class Datasources(QuerysetEndpoint):
|
|
|
126
126
|
datasource_id: str,
|
|
127
127
|
filepath: Optional[PathOrFileW] = None,
|
|
128
128
|
include_extract: bool = True,
|
|
129
|
-
no_extract: Optional[bool] = None,
|
|
130
129
|
) -> str:
|
|
131
|
-
return self.download_revision(
|
|
130
|
+
return self.download_revision(
|
|
131
|
+
datasource_id,
|
|
132
|
+
None,
|
|
133
|
+
filepath,
|
|
134
|
+
include_extract,
|
|
135
|
+
)
|
|
132
136
|
|
|
133
137
|
# Update datasource
|
|
134
138
|
@api(version="2.0")
|
|
@@ -351,17 +355,6 @@ class Datasources(QuerysetEndpoint):
|
|
|
351
355
|
def populate_permissions(self, item: DatasourceItem) -> None:
|
|
352
356
|
self._permissions.populate(item)
|
|
353
357
|
|
|
354
|
-
@api(version="2.0")
|
|
355
|
-
def update_permission(self, item, permission_item):
|
|
356
|
-
import warnings
|
|
357
|
-
|
|
358
|
-
warnings.warn(
|
|
359
|
-
"Server.datasources.update_permission is deprecated, "
|
|
360
|
-
"please use Server.datasources.update_permissions instead.",
|
|
361
|
-
DeprecationWarning,
|
|
362
|
-
)
|
|
363
|
-
self._permissions.update(item, permission_item)
|
|
364
|
-
|
|
365
358
|
@api(version="2.0")
|
|
366
359
|
def update_permissions(self, item: DatasourceItem, permission_item: List["PermissionsRule"]) -> None:
|
|
367
360
|
self._permissions.update(item, permission_item)
|
|
@@ -415,7 +408,6 @@ class Datasources(QuerysetEndpoint):
|
|
|
415
408
|
revision_number: str,
|
|
416
409
|
filepath: Optional[PathOrFileW] = None,
|
|
417
410
|
include_extract: bool = True,
|
|
418
|
-
no_extract: Optional[bool] = None,
|
|
419
411
|
) -> PathOrFileW:
|
|
420
412
|
if not datasource_id:
|
|
421
413
|
error = "Datasource ID undefined."
|
|
@@ -424,14 +416,6 @@ class Datasources(QuerysetEndpoint):
|
|
|
424
416
|
url = "{0}/{1}/content".format(self.baseurl, datasource_id)
|
|
425
417
|
else:
|
|
426
418
|
url = "{0}/{1}/revisions/{2}/content".format(self.baseurl, datasource_id, revision_number)
|
|
427
|
-
if no_extract is False or no_extract is True:
|
|
428
|
-
import warnings
|
|
429
|
-
|
|
430
|
-
warnings.warn(
|
|
431
|
-
"no_extract is deprecated, use include_extract instead.",
|
|
432
|
-
DeprecationWarning,
|
|
433
|
-
)
|
|
434
|
-
include_extract = not no_extract
|
|
435
419
|
|
|
436
420
|
if not include_extract:
|
|
437
421
|
url += "?includeExtract=False"
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
from tableauserverclient import datetime_helpers as datetime
|
|
2
2
|
|
|
3
|
+
import abc
|
|
3
4
|
from packaging.version import Version
|
|
4
5
|
from functools import wraps
|
|
5
6
|
from xml.etree.ElementTree import ParseError
|
|
6
|
-
from typing import Any, Callable, Dict, Optional, TYPE_CHECKING, Union
|
|
7
|
+
from typing import Any, Callable, Dict, Generic, List, Optional, TYPE_CHECKING, Tuple, TypeVar, Union
|
|
8
|
+
|
|
9
|
+
from tableauserverclient.models.pagination_item import PaginationItem
|
|
10
|
+
from tableauserverclient.server.request_options import RequestOptions
|
|
7
11
|
|
|
8
12
|
from .exceptions import (
|
|
9
13
|
ServerResponseError,
|
|
@@ -300,25 +304,36 @@ def parameter_added_in(**params):
|
|
|
300
304
|
return _decorator
|
|
301
305
|
|
|
302
306
|
|
|
303
|
-
|
|
307
|
+
T = TypeVar("T")
|
|
308
|
+
|
|
309
|
+
|
|
310
|
+
class QuerysetEndpoint(Endpoint, Generic[T]):
|
|
304
311
|
@api(version="2.0")
|
|
305
|
-
def all(self, *args, **kwargs):
|
|
306
|
-
|
|
312
|
+
def all(self, *args, page_size: Optional[int] = None, **kwargs) -> QuerySet[T]:
|
|
313
|
+
if args or kwargs:
|
|
314
|
+
raise ValueError(".all method takes no arguments.")
|
|
315
|
+
queryset = QuerySet(self, page_size=page_size)
|
|
307
316
|
return queryset
|
|
308
317
|
|
|
309
318
|
@api(version="2.0")
|
|
310
|
-
def filter(self, *_, **kwargs) -> QuerySet:
|
|
319
|
+
def filter(self, *_, page_size: Optional[int] = None, **kwargs) -> QuerySet[T]:
|
|
311
320
|
if _:
|
|
312
321
|
raise RuntimeError("Only keyword arguments accepted.")
|
|
313
|
-
queryset = QuerySet(self).filter(**kwargs)
|
|
322
|
+
queryset = QuerySet(self, page_size=page_size).filter(**kwargs)
|
|
314
323
|
return queryset
|
|
315
324
|
|
|
316
325
|
@api(version="2.0")
|
|
317
|
-
def order_by(self, *args, **kwargs):
|
|
326
|
+
def order_by(self, *args, **kwargs) -> QuerySet[T]:
|
|
327
|
+
if kwargs:
|
|
328
|
+
raise ValueError(".order_by does not accept keyword arguments.")
|
|
318
329
|
queryset = QuerySet(self).order_by(*args)
|
|
319
330
|
return queryset
|
|
320
331
|
|
|
321
332
|
@api(version="2.0")
|
|
322
|
-
def paginate(self, **kwargs):
|
|
333
|
+
def paginate(self, **kwargs) -> QuerySet[T]:
|
|
323
334
|
queryset = QuerySet(self).paginate(**kwargs)
|
|
324
335
|
return queryset
|
|
336
|
+
|
|
337
|
+
@abc.abstractmethod
|
|
338
|
+
def get(self, request_options: RequestOptions) -> Tuple[List[T], PaginationItem]:
|
|
339
|
+
raise NotImplementedError(f".get has not been implemented for {self.__class__.__qualname__}")
|
|
@@ -13,7 +13,7 @@ if TYPE_CHECKING:
|
|
|
13
13
|
from ..request_options import RequestOptions
|
|
14
14
|
|
|
15
15
|
|
|
16
|
-
class FlowRuns(QuerysetEndpoint):
|
|
16
|
+
class FlowRuns(QuerysetEndpoint[FlowRunItem]):
|
|
17
17
|
def __init__(self, parent_srv: "Server") -> None:
|
|
18
18
|
super(FlowRuns, self).__init__(parent_srv)
|
|
19
19
|
return None
|
|
@@ -50,7 +50,7 @@ PathOrFileR = Union[FilePath, FileObjectR]
|
|
|
50
50
|
PathOrFileW = Union[FilePath, FileObjectW]
|
|
51
51
|
|
|
52
52
|
|
|
53
|
-
class Flows(QuerysetEndpoint):
|
|
53
|
+
class Flows(QuerysetEndpoint[FlowItem]):
|
|
54
54
|
def __init__(self, parent_srv):
|
|
55
55
|
super(Flows, self).__init__(parent_srv)
|
|
56
56
|
self._resource_tagger = _ResourceTagger(parent_srv)
|
|
@@ -265,16 +265,6 @@ class Flows(QuerysetEndpoint):
|
|
|
265
265
|
def populate_permissions(self, item: FlowItem) -> None:
|
|
266
266
|
self._permissions.populate(item)
|
|
267
267
|
|
|
268
|
-
@api(version="3.3")
|
|
269
|
-
def update_permission(self, item, permission_item):
|
|
270
|
-
import warnings
|
|
271
|
-
|
|
272
|
-
warnings.warn(
|
|
273
|
-
"Server.flows.update_permission is deprecated, " "please use Server.flows.update_permissions instead.",
|
|
274
|
-
DeprecationWarning,
|
|
275
|
-
)
|
|
276
|
-
self._permissions.update(item, permission_item)
|
|
277
|
-
|
|
278
268
|
@api(version="3.3")
|
|
279
269
|
def update_permissions(self, item: FlowItem, permission_item: Iterable["PermissionsRule"]) -> None:
|
|
280
270
|
self._permissions.update(item, permission_item)
|
|
@@ -14,7 +14,7 @@ if TYPE_CHECKING:
|
|
|
14
14
|
from ..request_options import RequestOptions
|
|
15
15
|
|
|
16
16
|
|
|
17
|
-
class Groups(QuerysetEndpoint):
|
|
17
|
+
class Groups(QuerysetEndpoint[GroupItem]):
|
|
18
18
|
@property
|
|
19
19
|
def baseurl(self) -> str:
|
|
20
20
|
return "{0}/sites/{1}/groups".format(self.parent_srv.baseurl, self.parent_srv.site_id)
|
|
@@ -67,21 +67,7 @@ class Groups(QuerysetEndpoint):
|
|
|
67
67
|
logger.info("Deleted single group (ID: {0})".format(group_id))
|
|
68
68
|
|
|
69
69
|
@api(version="2.0")
|
|
70
|
-
def update(
|
|
71
|
-
self, group_item: GroupItem, default_site_role: Optional[str] = None, as_job: bool = False
|
|
72
|
-
) -> Union[GroupItem, JobItem]:
|
|
73
|
-
# (1/8/2021): Deprecated starting v0.15
|
|
74
|
-
if default_site_role is not None:
|
|
75
|
-
import warnings
|
|
76
|
-
|
|
77
|
-
warnings.simplefilter("always", DeprecationWarning)
|
|
78
|
-
warnings.warn(
|
|
79
|
-
'Groups.update(...default_site_role=""...) is deprecated, '
|
|
80
|
-
"please set the minimum_site_role field of GroupItem",
|
|
81
|
-
DeprecationWarning,
|
|
82
|
-
)
|
|
83
|
-
group_item.minimum_site_role = default_site_role
|
|
84
|
-
|
|
70
|
+
def update(self, group_item: GroupItem, as_job: bool = False) -> Union[GroupItem, JobItem]:
|
|
85
71
|
url = "{0}/{1}".format(self.baseurl, group_item.id)
|
|
86
72
|
|
|
87
73
|
if not group_item.id:
|
|
@@ -93,7 +79,7 @@ class Groups(QuerysetEndpoint):
|
|
|
93
79
|
elif as_job:
|
|
94
80
|
url = "?".join([url, "asJob=True"])
|
|
95
81
|
|
|
96
|
-
update_req = RequestFactory.Group.update_req(group_item
|
|
82
|
+
update_req = RequestFactory.Group.update_req(group_item)
|
|
97
83
|
server_response = self.put_request(url, update_req)
|
|
98
84
|
logger.info("Updated group item (ID: {0})".format(group_item.id))
|
|
99
85
|
if as_job:
|
|
@@ -11,7 +11,7 @@ from tableauserverclient.helpers.logging import logger
|
|
|
11
11
|
from typing import List, Optional, Tuple, Union
|
|
12
12
|
|
|
13
13
|
|
|
14
|
-
class Jobs(QuerysetEndpoint):
|
|
14
|
+
class Jobs(QuerysetEndpoint[JobItem]):
|
|
15
15
|
@property
|
|
16
16
|
def baseurl(self):
|
|
17
17
|
return "{0}/sites/{1}/jobs".format(self.parent_srv.baseurl, self.parent_srv.site_id)
|
|
@@ -42,9 +42,9 @@ def extract_values(obj, key):
|
|
|
42
42
|
|
|
43
43
|
|
|
44
44
|
def get_page_info(result):
|
|
45
|
-
next_page = extract_values(result, "hasNextPage")
|
|
46
|
-
cursor = extract_values(result, "endCursor")
|
|
47
|
-
return next_page, cursor
|
|
45
|
+
next_page = extract_values(result, "hasNextPage")
|
|
46
|
+
cursor = extract_values(result, "endCursor")
|
|
47
|
+
return next_page.pop() if next_page else None, cursor.pop() if cursor else None
|
|
48
48
|
|
|
49
49
|
|
|
50
50
|
class Metadata(Endpoint):
|
|
@@ -18,7 +18,7 @@ if TYPE_CHECKING:
|
|
|
18
18
|
from tableauserverclient.helpers.logging import logger
|
|
19
19
|
|
|
20
20
|
|
|
21
|
-
class Metrics(QuerysetEndpoint):
|
|
21
|
+
class Metrics(QuerysetEndpoint[MetricItem]):
|
|
22
22
|
def __init__(self, parent_srv: "Server") -> None:
|
|
23
23
|
super(Metrics, self).__init__(parent_srv)
|
|
24
24
|
self._resource_tagger = _ResourceTagger(parent_srv)
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
|
|
3
|
-
from .default_permissions_endpoint import _DefaultPermissionsEndpoint
|
|
4
|
-
from .endpoint import QuerysetEndpoint, api, XML_CONTENT_TYPE
|
|
5
|
-
from .exceptions import MissingRequiredFieldError
|
|
6
|
-
from .permissions_endpoint import _PermissionsEndpoint
|
|
3
|
+
from tableauserverclient.server.endpoint.default_permissions_endpoint import _DefaultPermissionsEndpoint
|
|
4
|
+
from tableauserverclient.server.endpoint.endpoint import QuerysetEndpoint, api, XML_CONTENT_TYPE
|
|
5
|
+
from tableauserverclient.server.endpoint.exceptions import MissingRequiredFieldError
|
|
6
|
+
from tableauserverclient.server.endpoint.permissions_endpoint import _PermissionsEndpoint
|
|
7
7
|
from tableauserverclient.server import RequestFactory, RequestOptions
|
|
8
8
|
from tableauserverclient.models import ProjectItem, PaginationItem, Resource
|
|
9
9
|
|
|
10
10
|
from typing import List, Optional, Tuple, TYPE_CHECKING
|
|
11
11
|
|
|
12
12
|
if TYPE_CHECKING:
|
|
13
|
-
from
|
|
14
|
-
from
|
|
13
|
+
from tableauserverclient.server.server import Server
|
|
14
|
+
from tableauserverclient.server.request_options import RequestOptions
|
|
15
15
|
|
|
16
16
|
from tableauserverclient.helpers.logging import logger
|
|
17
17
|
|
|
18
18
|
|
|
19
|
-
class Projects(QuerysetEndpoint):
|
|
19
|
+
class Projects(QuerysetEndpoint[ProjectItem]):
|
|
20
20
|
def __init__(self, parent_srv: "Server") -> None:
|
|
21
21
|
super(Projects, self).__init__(parent_srv)
|
|
22
22
|
|
|
@@ -75,17 +75,6 @@ class Projects(QuerysetEndpoint):
|
|
|
75
75
|
def populate_permissions(self, item: ProjectItem) -> None:
|
|
76
76
|
self._permissions.populate(item)
|
|
77
77
|
|
|
78
|
-
@api(version="2.0")
|
|
79
|
-
def update_permission(self, item, rules):
|
|
80
|
-
import warnings
|
|
81
|
-
|
|
82
|
-
warnings.warn(
|
|
83
|
-
"Server.projects.update_permission is deprecated, "
|
|
84
|
-
"please use Server.projects.update_permissions instead.",
|
|
85
|
-
DeprecationWarning,
|
|
86
|
-
)
|
|
87
|
-
return self._permissions.update(item, rules)
|
|
88
|
-
|
|
89
78
|
@api(version="2.0")
|
|
90
79
|
def update_permissions(self, item, rules):
|
|
91
80
|
return self._permissions.update(item, rules)
|
|
@@ -101,16 +101,6 @@ class Tables(Endpoint):
|
|
|
101
101
|
def populate_permissions(self, item):
|
|
102
102
|
self._permissions.populate(item)
|
|
103
103
|
|
|
104
|
-
@api(version="3.5")
|
|
105
|
-
def update_permission(self, item, rules):
|
|
106
|
-
import warnings
|
|
107
|
-
|
|
108
|
-
warnings.warn(
|
|
109
|
-
"Server.tables.update_permission is deprecated, " "please use Server.tables.update_permissions instead.",
|
|
110
|
-
DeprecationWarning,
|
|
111
|
-
)
|
|
112
|
-
return self._permissions.update(item, rules)
|
|
113
|
-
|
|
114
104
|
@api(version="3.5")
|
|
115
105
|
def update_permissions(self, item, rules):
|
|
116
106
|
return self._permissions.update(item, rules)
|
|
@@ -11,7 +11,7 @@ from ..pager import Pager
|
|
|
11
11
|
from tableauserverclient.helpers.logging import logger
|
|
12
12
|
|
|
13
13
|
|
|
14
|
-
class Users(QuerysetEndpoint):
|
|
14
|
+
class Users(QuerysetEndpoint[UserItem]):
|
|
15
15
|
@property
|
|
16
16
|
def baseurl(self) -> str:
|
|
17
17
|
return "{0}/sites/{1}/users".format(self.parent_srv.baseurl, self.parent_srv.site_id)
|
|
@@ -21,7 +21,7 @@ if TYPE_CHECKING:
|
|
|
21
21
|
)
|
|
22
22
|
|
|
23
23
|
|
|
24
|
-
class Views(QuerysetEndpoint):
|
|
24
|
+
class Views(QuerysetEndpoint[ViewItem]):
|
|
25
25
|
def __init__(self, parent_srv):
|
|
26
26
|
super(Views, self).__init__(parent_srv)
|
|
27
27
|
self._resource_tagger = _ResourceTagger(parent_srv)
|
|
@@ -50,12 +50,14 @@ class Views(QuerysetEndpoint):
|
|
|
50
50
|
return all_view_items, pagination_item
|
|
51
51
|
|
|
52
52
|
@api(version="3.1")
|
|
53
|
-
def get_by_id(self, view_id: str) -> ViewItem:
|
|
53
|
+
def get_by_id(self, view_id: str, usage: bool = False) -> ViewItem:
|
|
54
54
|
if not view_id:
|
|
55
55
|
error = "View item missing ID."
|
|
56
56
|
raise MissingRequiredFieldError(error)
|
|
57
57
|
logger.info("Querying single view (ID: {0})".format(view_id))
|
|
58
58
|
url = "{0}/{1}".format(self.baseurl, view_id)
|
|
59
|
+
if usage:
|
|
60
|
+
url += "?includeUsageStatistics=true"
|
|
59
61
|
server_response = self.get_request(url)
|
|
60
62
|
return ViewItem.from_response(server_response.content, self.parent_srv.namespace)[0]
|
|
61
63
|
|
|
@@ -56,7 +56,7 @@ PathOrFileR = Union[FilePath, FileObjectR]
|
|
|
56
56
|
PathOrFileW = Union[FilePath, FileObjectW]
|
|
57
57
|
|
|
58
58
|
|
|
59
|
-
class Workbooks(QuerysetEndpoint):
|
|
59
|
+
class Workbooks(QuerysetEndpoint[WorkbookItem]):
|
|
60
60
|
def __init__(self, parent_srv: "Server") -> None:
|
|
61
61
|
super(Workbooks, self).__init__(parent_srv)
|
|
62
62
|
self._resource_tagger = _ResourceTagger(parent_srv)
|
|
@@ -160,13 +160,6 @@ class Workbooks(QuerysetEndpoint):
|
|
|
160
160
|
updated_workbook = copy.copy(workbook_item)
|
|
161
161
|
return updated_workbook._parse_common_tags(server_response.content, self.parent_srv.namespace)
|
|
162
162
|
|
|
163
|
-
@api(version="2.3")
|
|
164
|
-
def update_conn(self, *args, **kwargs):
|
|
165
|
-
import warnings
|
|
166
|
-
|
|
167
|
-
warnings.warn("update_conn is deprecated, please use update_connection instead")
|
|
168
|
-
return self.update_connection(*args, **kwargs)
|
|
169
|
-
|
|
170
163
|
# Update workbook_connection
|
|
171
164
|
@api(version="2.3")
|
|
172
165
|
def update_connection(self, workbook_item: WorkbookItem, connection_item: ConnectionItem) -> ConnectionItem:
|
|
@@ -189,9 +182,13 @@ class Workbooks(QuerysetEndpoint):
|
|
|
189
182
|
workbook_id: str,
|
|
190
183
|
filepath: Optional[PathOrFileW] = None,
|
|
191
184
|
include_extract: bool = True,
|
|
192
|
-
no_extract: Optional[bool] = None,
|
|
193
185
|
) -> str:
|
|
194
|
-
return self.download_revision(
|
|
186
|
+
return self.download_revision(
|
|
187
|
+
workbook_id,
|
|
188
|
+
None,
|
|
189
|
+
filepath,
|
|
190
|
+
include_extract,
|
|
191
|
+
)
|
|
195
192
|
|
|
196
193
|
# Get all views of workbook
|
|
197
194
|
@api(version="2.0")
|
|
@@ -315,21 +312,11 @@ class Workbooks(QuerysetEndpoint):
|
|
|
315
312
|
workbook_item: WorkbookItem,
|
|
316
313
|
file: PathOrFileR,
|
|
317
314
|
mode: str,
|
|
318
|
-
connection_credentials: Optional["ConnectionCredentials"] = None,
|
|
319
315
|
connections: Optional[Sequence[ConnectionItem]] = None,
|
|
320
316
|
as_job: bool = False,
|
|
321
|
-
hidden_views: Optional[Sequence[str]] = None,
|
|
322
317
|
skip_connection_check: bool = False,
|
|
323
318
|
parameters=None,
|
|
324
319
|
):
|
|
325
|
-
if connection_credentials is not None:
|
|
326
|
-
import warnings
|
|
327
|
-
|
|
328
|
-
warnings.warn(
|
|
329
|
-
"connection_credentials is being deprecated. Use connections instead",
|
|
330
|
-
DeprecationWarning,
|
|
331
|
-
)
|
|
332
|
-
|
|
333
320
|
if isinstance(file, (str, os.PathLike)):
|
|
334
321
|
if not os.path.isfile(file):
|
|
335
322
|
error = "File path does not lead to an existing file."
|
|
@@ -391,12 +378,9 @@ class Workbooks(QuerysetEndpoint):
|
|
|
391
378
|
logger.info("Publishing {0} to server with chunking method (workbook over 64MB)".format(workbook_item.name))
|
|
392
379
|
upload_session_id = self.parent_srv.fileuploads.upload(file)
|
|
393
380
|
url = "{0}&uploadSessionId={1}".format(url, upload_session_id)
|
|
394
|
-
conn_creds = connection_credentials
|
|
395
381
|
xml_request, content_type = RequestFactory.Workbook.publish_req_chunked(
|
|
396
382
|
workbook_item,
|
|
397
|
-
connection_credentials=conn_creds,
|
|
398
383
|
connections=connections,
|
|
399
|
-
hidden_views=hidden_views,
|
|
400
384
|
)
|
|
401
385
|
else:
|
|
402
386
|
logger.info("Publishing {0} to server".format(filename))
|
|
@@ -411,14 +395,11 @@ class Workbooks(QuerysetEndpoint):
|
|
|
411
395
|
else:
|
|
412
396
|
raise TypeError("file should be a filepath or file object.")
|
|
413
397
|
|
|
414
|
-
conn_creds = connection_credentials
|
|
415
398
|
xml_request, content_type = RequestFactory.Workbook.publish_req(
|
|
416
399
|
workbook_item,
|
|
417
400
|
filename,
|
|
418
401
|
file_contents,
|
|
419
|
-
connection_credentials=conn_creds,
|
|
420
402
|
connections=connections,
|
|
421
|
-
hidden_views=hidden_views,
|
|
422
403
|
)
|
|
423
404
|
logger.debug("Request xml: {0} ".format(redact_xml(xml_request[:1000])))
|
|
424
405
|
|
|
@@ -468,7 +449,6 @@ class Workbooks(QuerysetEndpoint):
|
|
|
468
449
|
revision_number: Optional[str],
|
|
469
450
|
filepath: Optional[PathOrFileW] = None,
|
|
470
451
|
include_extract: bool = True,
|
|
471
|
-
no_extract: Optional[bool] = None,
|
|
472
452
|
) -> PathOrFileW:
|
|
473
453
|
if not workbook_id:
|
|
474
454
|
error = "Workbook ID undefined."
|
|
@@ -478,15 +458,6 @@ class Workbooks(QuerysetEndpoint):
|
|
|
478
458
|
else:
|
|
479
459
|
url = "{0}/{1}/revisions/{2}/content".format(self.baseurl, workbook_id, revision_number)
|
|
480
460
|
|
|
481
|
-
if no_extract is False or no_extract is True:
|
|
482
|
-
import warnings
|
|
483
|
-
|
|
484
|
-
warnings.warn(
|
|
485
|
-
"no_extract is deprecated, use include_extract instead.",
|
|
486
|
-
DeprecationWarning,
|
|
487
|
-
)
|
|
488
|
-
include_extract = not no_extract
|
|
489
|
-
|
|
490
461
|
if not include_extract:
|
|
491
462
|
url += "?includeExtract=False"
|
|
492
463
|
|