tableauserverclient 0.26__py3-none-any.whl → 0.28__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 +42 -1
- tableauserverclient/_version.py +4 -4
- tableauserverclient/helpers/logging.py +0 -2
- tableauserverclient/models/__init__.py +1 -1
- tableauserverclient/models/column_item.py +3 -0
- tableauserverclient/models/connection_credentials.py +7 -0
- tableauserverclient/models/custom_view_item.py +5 -0
- tableauserverclient/models/data_acceleration_report_item.py +3 -0
- tableauserverclient/models/datasource_item.py +0 -9
- tableauserverclient/models/group_item.py +1 -4
- tableauserverclient/models/interval_item.py +12 -0
- tableauserverclient/models/job_item.py +10 -1
- tableauserverclient/models/metric_item.py +4 -1
- tableauserverclient/models/pagination_item.py +3 -0
- tableauserverclient/models/permissions_item.py +7 -4
- tableauserverclient/models/project_item.py +2 -0
- tableauserverclient/models/schedule_item.py +6 -7
- tableauserverclient/models/server_info_item.py +1 -1
- tableauserverclient/models/site_item.py +3 -0
- tableauserverclient/models/subscription_item.py +8 -0
- tableauserverclient/models/table_item.py +6 -0
- tableauserverclient/models/tableau_auth.py +41 -6
- tableauserverclient/models/user_item.py +4 -1
- tableauserverclient/models/view_item.py +4 -1
- tableauserverclient/models/workbook_item.py +4 -1
- tableauserverclient/server/endpoint/auth_endpoint.py +28 -7
- tableauserverclient/server/endpoint/favorites_endpoint.py +0 -1
- tableauserverclient/server/endpoint/groups_endpoint.py +4 -1
- tableauserverclient/server/endpoint/projects_endpoint.py +2 -0
- tableauserverclient/server/endpoint/tasks_endpoint.py +11 -0
- tableauserverclient/server/filter.py +5 -1
- tableauserverclient/server/request_factory.py +28 -0
- tableauserverclient/server/request_options.py +1 -0
- {tableauserverclient-0.26.dist-info → tableauserverclient-0.28.dist-info}/METADATA +12 -10
- {tableauserverclient-0.26.dist-info → tableauserverclient-0.28.dist-info}/RECORD +39 -39
- {tableauserverclient-0.26.dist-info → tableauserverclient-0.28.dist-info}/WHEEL +1 -1
- {tableauserverclient-0.26.dist-info → tableauserverclient-0.28.dist-info}/LICENSE +0 -0
- {tableauserverclient-0.26.dist-info → tableauserverclient-0.28.dist-info}/LICENSE.versioneer +0 -0
- {tableauserverclient-0.26.dist-info → tableauserverclient-0.28.dist-info}/top_level.txt +0 -0
tableauserverclient/__init__.py
CHANGED
|
@@ -1,6 +1,47 @@
|
|
|
1
1
|
from ._version import get_versions
|
|
2
2
|
from .namespace import NEW_NAMESPACE as DEFAULT_NAMESPACE
|
|
3
|
-
from .models import
|
|
3
|
+
from .models import (
|
|
4
|
+
BackgroundJobItem,
|
|
5
|
+
ColumnItem,
|
|
6
|
+
ConnectionCredentials,
|
|
7
|
+
ConnectionItem,
|
|
8
|
+
CustomViewItem,
|
|
9
|
+
DQWItem,
|
|
10
|
+
DailyInterval,
|
|
11
|
+
DataAlertItem,
|
|
12
|
+
DatabaseItem,
|
|
13
|
+
DatasourceItem,
|
|
14
|
+
FavoriteItem,
|
|
15
|
+
FlowItem,
|
|
16
|
+
FlowRunItem,
|
|
17
|
+
FileuploadItem,
|
|
18
|
+
GroupItem,
|
|
19
|
+
HourlyInterval,
|
|
20
|
+
IntervalItem,
|
|
21
|
+
JobItem,
|
|
22
|
+
JWTAuth,
|
|
23
|
+
MetricItem,
|
|
24
|
+
MonthlyInterval,
|
|
25
|
+
PaginationItem,
|
|
26
|
+
Permission,
|
|
27
|
+
PermissionsRule,
|
|
28
|
+
PersonalAccessTokenAuth,
|
|
29
|
+
ProjectItem,
|
|
30
|
+
RevisionItem,
|
|
31
|
+
ScheduleItem,
|
|
32
|
+
SiteItem,
|
|
33
|
+
ServerInfoItem,
|
|
34
|
+
SubscriptionItem,
|
|
35
|
+
TableItem,
|
|
36
|
+
TableauAuth,
|
|
37
|
+
Target,
|
|
38
|
+
TaskItem,
|
|
39
|
+
UserItem,
|
|
40
|
+
ViewItem,
|
|
41
|
+
WebhookItem,
|
|
42
|
+
WeeklyInterval,
|
|
43
|
+
WorkbookItem,
|
|
44
|
+
)
|
|
4
45
|
from .server import (
|
|
5
46
|
CSVRequestOptions,
|
|
6
47
|
ExcelRequestOptions,
|
tableauserverclient/_version.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
# This file was generated by 'versioneer.py' (0.
|
|
2
|
+
# This file was generated by 'versioneer.py' (0.29) from
|
|
3
3
|
# revision-control system data, or from the parent directory name of an
|
|
4
4
|
# unpacked source archive. Distribution tarballs contain a pre-generated copy
|
|
5
5
|
# of this file.
|
|
@@ -8,11 +8,11 @@ import json
|
|
|
8
8
|
|
|
9
9
|
version_json = '''
|
|
10
10
|
{
|
|
11
|
-
"date": "2023-
|
|
11
|
+
"date": "2023-10-04T00:33:03-0700",
|
|
12
12
|
"dirty": false,
|
|
13
13
|
"error": null,
|
|
14
|
-
"full-revisionid": "
|
|
15
|
-
"version": "0.
|
|
14
|
+
"full-revisionid": "72eb3c8500193e4f20defa20c8a6f8bbf34b2f43",
|
|
15
|
+
"version": "0.28"
|
|
16
16
|
}
|
|
17
17
|
''' # END VERSION_JSON
|
|
18
18
|
|
|
@@ -31,7 +31,7 @@ from .server_info_item import ServerInfoItem
|
|
|
31
31
|
from .site_item import SiteItem
|
|
32
32
|
from .subscription_item import SubscriptionItem
|
|
33
33
|
from .table_item import TableItem
|
|
34
|
-
from .tableau_auth import Credentials, TableauAuth, PersonalAccessTokenAuth
|
|
34
|
+
from .tableau_auth import Credentials, TableauAuth, PersonalAccessTokenAuth, JWTAuth
|
|
35
35
|
from .tableau_types import Resource, TableauItem, plural_type
|
|
36
36
|
from .tag_item import TagItem
|
|
37
37
|
from .target import Target
|
|
@@ -15,6 +15,13 @@ class ConnectionCredentials(object):
|
|
|
15
15
|
self.embed = embed
|
|
16
16
|
self.oauth = oauth
|
|
17
17
|
|
|
18
|
+
def __repr__(self):
|
|
19
|
+
if self.password:
|
|
20
|
+
print = "redacted"
|
|
21
|
+
else:
|
|
22
|
+
print = "None"
|
|
23
|
+
return f"<{self.__class__.__name__} name={self.name} password={print} embed={self.embed} oauth={self.oauth} >"
|
|
24
|
+
|
|
18
25
|
@property
|
|
19
26
|
def embed(self):
|
|
20
27
|
return self._embed
|
|
@@ -134,6 +134,7 @@ class CustomViewItem(object):
|
|
|
134
134
|
cv_item._content_url = custom_view_xml.get("contentUrl", None)
|
|
135
135
|
cv_item._id = custom_view_xml.get("id", None)
|
|
136
136
|
cv_item._name = custom_view_xml.get("name", None)
|
|
137
|
+
cv_item._shared = string_to_bool(custom_view_xml.get("shared", None))
|
|
137
138
|
|
|
138
139
|
if owner_elem is not None:
|
|
139
140
|
parsed_owners = UserItem.from_response_as_owner(tostring(custom_view_xml), ns)
|
|
@@ -154,3 +155,7 @@ class CustomViewItem(object):
|
|
|
154
155
|
|
|
155
156
|
all_view_items.append(cv_item)
|
|
156
157
|
return all_view_items
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
def string_to_bool(s: Optional[str]) -> bool:
|
|
161
|
+
return (s or "").lower() == "true"
|
|
@@ -46,6 +46,9 @@ class DataAccelerationReportItem(object):
|
|
|
46
46
|
def __init__(self, comparison_records):
|
|
47
47
|
self._comparison_records = comparison_records
|
|
48
48
|
|
|
49
|
+
def __repr__(self):
|
|
50
|
+
return f"<(deprecated)DataAccelerationReportItem site={self.site} sheet={sheet_uri}>"
|
|
51
|
+
|
|
49
52
|
@property
|
|
50
53
|
def comparison_records(self):
|
|
51
54
|
return self._comparison_records
|
|
@@ -326,17 +326,8 @@ class DatasourceItem(object):
|
|
|
326
326
|
updated_at = parse_datetime(datasource_xml.get("updatedAt", None))
|
|
327
327
|
certification_note = datasource_xml.get("certificationNote", None)
|
|
328
328
|
certified = str(datasource_xml.get("isCertified", None)).lower() == "true"
|
|
329
|
-
certification_note = datasource_xml.get("certificationNote", None)
|
|
330
|
-
certified = str(datasource_xml.get("isCertified", None)).lower() == "true"
|
|
331
|
-
content_url = datasource_xml.get("contentUrl", None)
|
|
332
|
-
created_at = parse_datetime(datasource_xml.get("createdAt", None))
|
|
333
|
-
datasource_type = datasource_xml.get("type", None)
|
|
334
|
-
description = datasource_xml.get("description", None)
|
|
335
329
|
encrypt_extracts = datasource_xml.get("encryptExtracts", None)
|
|
336
330
|
has_extracts = datasource_xml.get("hasExtracts", None)
|
|
337
|
-
id_ = datasource_xml.get("id", None)
|
|
338
|
-
name = datasource_xml.get("name", None)
|
|
339
|
-
updated_at = parse_datetime(datasource_xml.get("updatedAt", None))
|
|
340
331
|
use_remote_query_agent = datasource_xml.get("useRemoteQueryAgent", None)
|
|
341
332
|
webpage_url = datasource_xml.get("webpageUrl", None)
|
|
342
333
|
|
|
@@ -26,11 +26,9 @@ class GroupItem(object):
|
|
|
26
26
|
self.name: Optional[str] = name
|
|
27
27
|
self.domain_name: Optional[str] = domain_name
|
|
28
28
|
|
|
29
|
-
def
|
|
29
|
+
def __repr__(self):
|
|
30
30
|
return "{}({!r})".format(self.__class__.__name__, self.__dict__)
|
|
31
31
|
|
|
32
|
-
__repr__ = __str__
|
|
33
|
-
|
|
34
32
|
@property
|
|
35
33
|
def domain_name(self) -> Optional[str]:
|
|
36
34
|
return self._domain_name
|
|
@@ -48,7 +46,6 @@ class GroupItem(object):
|
|
|
48
46
|
return self._name
|
|
49
47
|
|
|
50
48
|
@name.setter
|
|
51
|
-
@property_not_empty
|
|
52
49
|
def name(self, value: str) -> None:
|
|
53
50
|
self._name = value
|
|
54
51
|
|
|
@@ -31,6 +31,9 @@ class HourlyInterval(object):
|
|
|
31
31
|
self.end_time = end_time
|
|
32
32
|
self.interval = interval_value
|
|
33
33
|
|
|
34
|
+
def __repr__(self):
|
|
35
|
+
return f"<{self.__class__.__name__} start={self.start_time} end={self.end_time} interval={self.interval}>"
|
|
36
|
+
|
|
34
37
|
@property
|
|
35
38
|
def _frequency(self):
|
|
36
39
|
return IntervalItem.Frequency.Hourly
|
|
@@ -86,6 +89,9 @@ class DailyInterval(object):
|
|
|
86
89
|
self.start_time = start_time
|
|
87
90
|
self.interval = interval_values
|
|
88
91
|
|
|
92
|
+
def __repr__(self):
|
|
93
|
+
return f"<{self.__class__.__name__} start={self.start_time} interval={self.interval}>"
|
|
94
|
+
|
|
89
95
|
@property
|
|
90
96
|
def _frequency(self):
|
|
91
97
|
return IntervalItem.Frequency.Daily
|
|
@@ -114,6 +120,9 @@ class WeeklyInterval(object):
|
|
|
114
120
|
self.start_time = start_time
|
|
115
121
|
self.interval = interval_values
|
|
116
122
|
|
|
123
|
+
def __repr__(self):
|
|
124
|
+
return f"<{self.__class__.__name__} start={self.start_time} interval={self.interval}>"
|
|
125
|
+
|
|
117
126
|
@property
|
|
118
127
|
def _frequency(self):
|
|
119
128
|
return IntervalItem.Frequency.Weekly
|
|
@@ -148,6 +157,9 @@ class MonthlyInterval(object):
|
|
|
148
157
|
self.start_time = start_time
|
|
149
158
|
self.interval = str(interval_value)
|
|
150
159
|
|
|
160
|
+
def __repr__(self):
|
|
161
|
+
return f"<{self.__class__.__name__} start={self.start_time} interval={self.interval}>"
|
|
162
|
+
|
|
151
163
|
@property
|
|
152
164
|
def _frequency(self):
|
|
153
165
|
return IntervalItem.Frequency.Monthly
|
|
@@ -117,12 +117,15 @@ class JobItem(object):
|
|
|
117
117
|
def updated_at(self) -> Optional[datetime.datetime]:
|
|
118
118
|
return self._updated_at
|
|
119
119
|
|
|
120
|
-
def
|
|
120
|
+
def __str__(self):
|
|
121
121
|
return (
|
|
122
122
|
"<Job#{_id} {_type} created_at({_created_at}) started_at({_started_at}) updated_at({_updated_at}) completed_at({_completed_at})"
|
|
123
123
|
" progress ({_progress}) finish_code({_finish_code})>".format(**self.__dict__)
|
|
124
124
|
)
|
|
125
125
|
|
|
126
|
+
def __repr__(self):
|
|
127
|
+
return self.__str__() + " { " + ", ".join(" % s: % s" % item for item in vars(self).items()) + "}"
|
|
128
|
+
|
|
126
129
|
@classmethod
|
|
127
130
|
def from_response(cls, xml, ns) -> List["JobItem"]:
|
|
128
131
|
parsed_response = fromstring(xml)
|
|
@@ -202,6 +205,12 @@ class BackgroundJobItem(object):
|
|
|
202
205
|
self._title = title
|
|
203
206
|
self._subtitle = subtitle
|
|
204
207
|
|
|
208
|
+
def __str__(self):
|
|
209
|
+
return f"<{self.__class__.name} {self._id} {self._type}>"
|
|
210
|
+
|
|
211
|
+
def __repr__(self):
|
|
212
|
+
return self.__str__() + " { " + ", ".join(" % s: % s" % item for item in vars(self).items()) + "}"
|
|
213
|
+
|
|
205
214
|
@property
|
|
206
215
|
def id(self) -> str:
|
|
207
216
|
return self._id
|
|
@@ -115,9 +115,12 @@ class MetricItem(object):
|
|
|
115
115
|
def _set_permissions(self, permissions):
|
|
116
116
|
self._permissions = permissions
|
|
117
117
|
|
|
118
|
-
def
|
|
118
|
+
def __str__(self):
|
|
119
119
|
return "<MetricItem# name={_name} id={_id} owner_id={_owner_id}>".format(**vars(self))
|
|
120
120
|
|
|
121
|
+
def __repr__(self):
|
|
122
|
+
return self.__str__() + " { " + ", ".join(" % s: % s" % item for item in vars(self).items()) + "}"
|
|
123
|
+
|
|
121
124
|
@classmethod
|
|
122
125
|
def from_response(
|
|
123
126
|
cls,
|
|
@@ -7,6 +7,9 @@ class PaginationItem(object):
|
|
|
7
7
|
self._page_size = None
|
|
8
8
|
self._total_available = None
|
|
9
9
|
|
|
10
|
+
def __repr__(self):
|
|
11
|
+
return f"<PaginationItem page_number={self._page_number} page_size={self._page_size} total={self._total_available}>"
|
|
12
|
+
|
|
10
13
|
@property
|
|
11
14
|
def page_number(self) -> int:
|
|
12
15
|
return self._page_number
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import logging
|
|
2
1
|
import xml.etree.ElementTree as ET
|
|
3
2
|
from typing import Dict, List, Optional
|
|
4
3
|
|
|
@@ -17,6 +16,9 @@ class Permission:
|
|
|
17
16
|
Allow = "Allow"
|
|
18
17
|
Deny = "Deny"
|
|
19
18
|
|
|
19
|
+
def __repr__(self):
|
|
20
|
+
return "<Enum Mode: Allow | Deny>"
|
|
21
|
+
|
|
20
22
|
class Capability:
|
|
21
23
|
AddComment = "AddComment"
|
|
22
24
|
ChangeHierarchy = "ChangeHierarchy"
|
|
@@ -39,17 +41,18 @@ class Permission:
|
|
|
39
41
|
CreateRefreshMetrics = "CreateRefreshMetrics"
|
|
40
42
|
SaveAs = "SaveAs"
|
|
41
43
|
|
|
44
|
+
def __repr__(self):
|
|
45
|
+
return "<Enum Capability: AddComment | ChangeHierarchy | ChangePermission ... (17 more) >"
|
|
46
|
+
|
|
42
47
|
|
|
43
48
|
class PermissionsRule(object):
|
|
44
49
|
def __init__(self, grantee: ResourceReference, capabilities: Dict[str, str]) -> None:
|
|
45
50
|
self.grantee = grantee
|
|
46
51
|
self.capabilities = capabilities
|
|
47
52
|
|
|
48
|
-
def
|
|
53
|
+
def __repr__(self):
|
|
49
54
|
return "<PermissionsRule grantee={}, capabilities={}>".format(self.grantee, self.capabilities)
|
|
50
55
|
|
|
51
|
-
__repr__ = __str__
|
|
52
|
-
|
|
53
56
|
@classmethod
|
|
54
57
|
def from_response(cls, resp, ns=None) -> List["PermissionsRule"]:
|
|
55
58
|
parsed_response = fromstring(resp)
|
|
@@ -25,6 +25,7 @@ class ProjectItem(object):
|
|
|
25
25
|
description: Optional[str] = None,
|
|
26
26
|
content_permissions: Optional[str] = None,
|
|
27
27
|
parent_id: Optional[str] = None,
|
|
28
|
+
samples: Optional[bool] = None,
|
|
28
29
|
) -> None:
|
|
29
30
|
self._content_permissions = None
|
|
30
31
|
self._id: Optional[str] = None
|
|
@@ -32,6 +33,7 @@ class ProjectItem(object):
|
|
|
32
33
|
self.name: str = name
|
|
33
34
|
self.content_permissions: Optional[str] = content_permissions
|
|
34
35
|
self.parent_id: Optional[str] = parent_id
|
|
36
|
+
self._samples: Optional[bool] = samples
|
|
35
37
|
|
|
36
38
|
self._permissions = None
|
|
37
39
|
self._default_workbook_permissions = None
|
|
@@ -14,8 +14,6 @@ from .interval_item import (
|
|
|
14
14
|
)
|
|
15
15
|
from .property_decorators import (
|
|
16
16
|
property_is_enum,
|
|
17
|
-
property_not_nullable,
|
|
18
|
-
property_is_int,
|
|
19
17
|
)
|
|
20
18
|
|
|
21
19
|
Interval = Union[HourlyInterval, DailyInterval, WeeklyInterval, MonthlyInterval]
|
|
@@ -27,6 +25,7 @@ class ScheduleItem(object):
|
|
|
27
25
|
Flow = "Flow"
|
|
28
26
|
Subscription = "Subscription"
|
|
29
27
|
DataAcceleration = "DataAcceleration"
|
|
28
|
+
ActiveDirectorySync = "ActiveDirectorySync"
|
|
30
29
|
|
|
31
30
|
class ExecutionOrder:
|
|
32
31
|
Parallel = "Parallel"
|
|
@@ -49,9 +48,12 @@ class ScheduleItem(object):
|
|
|
49
48
|
self.priority: int = priority
|
|
50
49
|
self.schedule_type: str = schedule_type
|
|
51
50
|
|
|
52
|
-
def
|
|
51
|
+
def __str__(self):
|
|
53
52
|
return '<Schedule#{_id} "{_name}" {interval_item}>'.format(**vars(self))
|
|
54
53
|
|
|
54
|
+
def __repr__(self):
|
|
55
|
+
return self.__str__() + " { " + ", ".join(" % s: % s" % item for item in vars(self).items()) + "}"
|
|
56
|
+
|
|
55
57
|
@property
|
|
56
58
|
def created_at(self) -> Optional[datetime]:
|
|
57
59
|
return self._created_at
|
|
@@ -74,11 +76,10 @@ class ScheduleItem(object):
|
|
|
74
76
|
return self._id
|
|
75
77
|
|
|
76
78
|
@property
|
|
77
|
-
def name(self) -> str:
|
|
79
|
+
def name(self) -> Optional[str]:
|
|
78
80
|
return self._name
|
|
79
81
|
|
|
80
82
|
@name.setter
|
|
81
|
-
@property_not_nullable
|
|
82
83
|
def name(self, value: str):
|
|
83
84
|
self._name = value
|
|
84
85
|
|
|
@@ -91,7 +92,6 @@ class ScheduleItem(object):
|
|
|
91
92
|
return self._priority
|
|
92
93
|
|
|
93
94
|
@priority.setter
|
|
94
|
-
@property_is_int(range=(1, 100))
|
|
95
95
|
def priority(self, value: int):
|
|
96
96
|
self._priority = value
|
|
97
97
|
|
|
@@ -101,7 +101,6 @@ class ScheduleItem(object):
|
|
|
101
101
|
|
|
102
102
|
@schedule_type.setter
|
|
103
103
|
@property_is_enum(Type)
|
|
104
|
-
@property_not_nullable
|
|
105
104
|
def schedule_type(self, value: str):
|
|
106
105
|
self._schedule_type = value
|
|
107
106
|
|
|
@@ -39,6 +39,9 @@ class SiteItem(object):
|
|
|
39
39
|
+ ">"
|
|
40
40
|
)
|
|
41
41
|
|
|
42
|
+
def __repr__(self):
|
|
43
|
+
return self.__str__() + " { " + ", ".join(" % s: % s" % item for item in vars(self).items()) + "}"
|
|
44
|
+
|
|
42
45
|
class AdminMode:
|
|
43
46
|
ContentAndUsers: str = "ContentAndUsers"
|
|
44
47
|
ContentOnly: str = "ContentOnly"
|
|
@@ -4,6 +4,7 @@ from defusedxml.ElementTree import fromstring
|
|
|
4
4
|
|
|
5
5
|
from .property_decorators import property_is_boolean
|
|
6
6
|
from .target import Target
|
|
7
|
+
from tableauserverclient.models import ScheduleItem
|
|
7
8
|
|
|
8
9
|
if TYPE_CHECKING:
|
|
9
10
|
from .target import Target
|
|
@@ -23,6 +24,7 @@ class SubscriptionItem(object):
|
|
|
23
24
|
self.suspended = False
|
|
24
25
|
self.target = target
|
|
25
26
|
self.user_id = user_id
|
|
27
|
+
self.schedule = None
|
|
26
28
|
|
|
27
29
|
def __repr__(self) -> str:
|
|
28
30
|
if self.id is not None:
|
|
@@ -92,9 +94,14 @@ class SubscriptionItem(object):
|
|
|
92
94
|
|
|
93
95
|
# Schedule element
|
|
94
96
|
schedule_id = None
|
|
97
|
+
schedule = None
|
|
95
98
|
if schedule_element is not None:
|
|
96
99
|
schedule_id = schedule_element.get("id", None)
|
|
97
100
|
|
|
101
|
+
# If schedule id is not provided, then TOL with full schedule provided
|
|
102
|
+
if schedule_id is None:
|
|
103
|
+
schedule = ScheduleItem.from_element(element, ns)
|
|
104
|
+
|
|
98
105
|
# Content element
|
|
99
106
|
target = None
|
|
100
107
|
send_if_view_empty = None
|
|
@@ -127,6 +134,7 @@ class SubscriptionItem(object):
|
|
|
127
134
|
sub.page_size_option = page_size_option
|
|
128
135
|
sub.send_if_view_empty = send_if_view_empty
|
|
129
136
|
sub.suspended = suspended
|
|
137
|
+
sub.schedule = schedule
|
|
130
138
|
|
|
131
139
|
return sub
|
|
132
140
|
|
|
@@ -19,6 +19,12 @@ class TableItem(object):
|
|
|
19
19
|
self._columns = None
|
|
20
20
|
self._data_quality_warnings = None
|
|
21
21
|
|
|
22
|
+
def __str__(self):
|
|
23
|
+
return f"<{self.__class__.__name__} {self._id} {self._name} >"
|
|
24
|
+
|
|
25
|
+
def __repr__(self):
|
|
26
|
+
return self.__str__() + " { " + ", ".join(" % s: % s" % item for item in vars(self).items()) + "}"
|
|
27
|
+
|
|
22
28
|
@property
|
|
23
29
|
def permissions(self):
|
|
24
30
|
if self._permissions is None:
|
|
@@ -1,13 +1,18 @@
|
|
|
1
|
-
|
|
1
|
+
import abc
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class Credentials(abc.ABC):
|
|
2
5
|
def __init__(self, site_id=None, user_id_to_impersonate=None):
|
|
3
6
|
self.site_id = site_id or ""
|
|
4
7
|
self.user_id_to_impersonate = user_id_to_impersonate or None
|
|
5
8
|
|
|
6
9
|
@property
|
|
10
|
+
@abc.abstractmethod
|
|
7
11
|
def credentials(self):
|
|
8
12
|
credentials = "Credentials can be username/password, Personal Access Token, or JWT"
|
|
9
13
|
+"This method returns values to set as an attribute on the credentials element of the request"
|
|
10
14
|
|
|
15
|
+
@abc.abstractmethod
|
|
11
16
|
def __repr__(self):
|
|
12
17
|
return "All Credentials types must have a debug display that does not print secrets"
|
|
13
18
|
|
|
@@ -38,7 +43,11 @@ class TableauAuth(Credentials):
|
|
|
38
43
|
return {"name": self.username, "password": self.password}
|
|
39
44
|
|
|
40
45
|
def __repr__(self):
|
|
41
|
-
|
|
46
|
+
if self.user_id_to_impersonate:
|
|
47
|
+
uid = f", user_id_to_impersonate=f{self.user_id_to_impersonate}"
|
|
48
|
+
else:
|
|
49
|
+
uid = ""
|
|
50
|
+
return f"<Credentials username={self.username} password=redacted (site={self.site_id}{uid})>"
|
|
42
51
|
|
|
43
52
|
@property
|
|
44
53
|
def site(self):
|
|
@@ -51,11 +60,12 @@ class TableauAuth(Credentials):
|
|
|
51
60
|
self.site_id = value
|
|
52
61
|
|
|
53
62
|
|
|
63
|
+
# A Tableau-generated Personal Access Token
|
|
54
64
|
class PersonalAccessTokenAuth(Credentials):
|
|
55
|
-
def __init__(self, token_name, personal_access_token, site_id=None):
|
|
65
|
+
def __init__(self, token_name, personal_access_token, site_id=None, user_id_to_impersonate=None):
|
|
56
66
|
if personal_access_token is None or token_name is None:
|
|
57
67
|
raise TabError("Must provide a token and token name when using PAT authentication")
|
|
58
|
-
super().__init__(site_id=site_id)
|
|
68
|
+
super().__init__(site_id=site_id, user_id_to_impersonate=user_id_to_impersonate)
|
|
59
69
|
self.token_name = token_name
|
|
60
70
|
self.personal_access_token = personal_access_token
|
|
61
71
|
|
|
@@ -67,6 +77,31 @@ class PersonalAccessTokenAuth(Credentials):
|
|
|
67
77
|
}
|
|
68
78
|
|
|
69
79
|
def __repr__(self):
|
|
70
|
-
|
|
71
|
-
|
|
80
|
+
if self.user_id_to_impersonate:
|
|
81
|
+
uid = f", user_id_to_impersonate=f{self.user_id_to_impersonate}"
|
|
82
|
+
else:
|
|
83
|
+
uid = ""
|
|
84
|
+
return (
|
|
85
|
+
f"<PersonalAccessToken name={self.token_name} token={self.personal_access_token[:2]}..."
|
|
86
|
+
f"(site={self.site_id}{uid} >"
|
|
72
87
|
)
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
# A standard JWT generated specifically for Tableau
|
|
91
|
+
class JWTAuth(Credentials):
|
|
92
|
+
def __init__(self, jwt: str, site_id=None, user_id_to_impersonate=None):
|
|
93
|
+
if jwt is None:
|
|
94
|
+
raise TabError("Must provide a JWT token when using JWT authentication")
|
|
95
|
+
super().__init__(site_id, user_id_to_impersonate)
|
|
96
|
+
self.jwt = jwt
|
|
97
|
+
|
|
98
|
+
@property
|
|
99
|
+
def credentials(self):
|
|
100
|
+
return {"jwt": self.jwt}
|
|
101
|
+
|
|
102
|
+
def __repr__(self):
|
|
103
|
+
if self.user_id_to_impersonate:
|
|
104
|
+
uid = f", user_id_to_impersonate=f{self.user_id_to_impersonate}"
|
|
105
|
+
else:
|
|
106
|
+
uid = ""
|
|
107
|
+
return f"<{self.__class__.__qualname__} jwt={self.jwt[:5]}... (site={self.site_id}{uid})>"
|
|
@@ -67,10 +67,13 @@ class UserItem(object):
|
|
|
67
67
|
|
|
68
68
|
return None
|
|
69
69
|
|
|
70
|
-
def
|
|
70
|
+
def __str__(self) -> str:
|
|
71
71
|
str_site_role = self.site_role or "None"
|
|
72
72
|
return "<User {} name={} role={}>".format(self.id, self.name, str_site_role)
|
|
73
73
|
|
|
74
|
+
def __repr__(self):
|
|
75
|
+
return self.__str__() + " { " + ", ".join(" % s: % s" % item for item in vars(self).items()) + "}"
|
|
76
|
+
|
|
74
77
|
@property
|
|
75
78
|
def auth_setting(self) -> Optional[str]:
|
|
76
79
|
return self._auth_setting
|
|
@@ -32,11 +32,14 @@ class ViewItem(object):
|
|
|
32
32
|
self._permissions: Optional[Callable[[], List[PermissionsRule]]] = None
|
|
33
33
|
self.tags: Set[str] = set()
|
|
34
34
|
|
|
35
|
-
def
|
|
35
|
+
def __str__(self):
|
|
36
36
|
return "<ViewItem {0} '{1}' contentUrl='{2}' project={3}>".format(
|
|
37
37
|
self._id, self.name, self.content_url, self.project_id
|
|
38
38
|
)
|
|
39
39
|
|
|
40
|
+
def __repr__(self):
|
|
41
|
+
return self.__str__() + " { " + ", ".join(" % s: % s" % item for item in vars(self).items()) + "}"
|
|
42
|
+
|
|
40
43
|
def _set_preview_image(self, preview_image):
|
|
41
44
|
self._preview_image = preview_image
|
|
42
45
|
|
|
@@ -53,11 +53,14 @@ class WorkbookItem(object):
|
|
|
53
53
|
|
|
54
54
|
return None
|
|
55
55
|
|
|
56
|
-
def
|
|
56
|
+
def __str__(self):
|
|
57
57
|
return "<WorkbookItem {0} '{1}' contentUrl='{2}' project={3}>".format(
|
|
58
58
|
self._id, self.name, self.content_url, self.project_id
|
|
59
59
|
)
|
|
60
60
|
|
|
61
|
+
def __repr__(self):
|
|
62
|
+
return self.__str__() + " { " + ", ".join(" % s: % s" % item for item in vars(self).items()) + "}"
|
|
63
|
+
|
|
61
64
|
@property
|
|
62
65
|
def connections(self) -> List[ConnectionItem]:
|
|
63
66
|
if self._connections is None:
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import logging
|
|
2
|
+
from typing import TYPE_CHECKING
|
|
3
|
+
import warnings
|
|
2
4
|
|
|
3
5
|
from defusedxml.ElementTree import fromstring
|
|
4
6
|
|
|
@@ -8,6 +10,10 @@ from ..request_factory import RequestFactory
|
|
|
8
10
|
|
|
9
11
|
from tableauserverclient.helpers.logging import logger
|
|
10
12
|
|
|
13
|
+
if TYPE_CHECKING:
|
|
14
|
+
from tableauserverclient.models.site_item import SiteItem
|
|
15
|
+
from tableauserverclient.models.tableau_auth import Credentials
|
|
16
|
+
|
|
11
17
|
|
|
12
18
|
class Auth(Endpoint):
|
|
13
19
|
class contextmgr(object):
|
|
@@ -21,11 +27,21 @@ class Auth(Endpoint):
|
|
|
21
27
|
self._callback()
|
|
22
28
|
|
|
23
29
|
@property
|
|
24
|
-
def baseurl(self):
|
|
30
|
+
def baseurl(self) -> str:
|
|
25
31
|
return "{0}/auth".format(self.parent_srv.baseurl)
|
|
26
32
|
|
|
27
33
|
@api(version="2.0")
|
|
28
|
-
def sign_in(self, auth_req):
|
|
34
|
+
def sign_in(self, auth_req: "Credentials") -> contextmgr:
|
|
35
|
+
"""
|
|
36
|
+
Sign in to a Tableau Server or Tableau Online using a credentials object.
|
|
37
|
+
|
|
38
|
+
The credentials object can either be a TableauAuth object, a
|
|
39
|
+
PersonalAccessTokenAuth object, or a JWTAuth object. This method now
|
|
40
|
+
accepts them all. The object should be populated with the site_id and
|
|
41
|
+
optionally a user_id to impersonate.
|
|
42
|
+
|
|
43
|
+
Creates a context manager that will sign out of the server upon exit.
|
|
44
|
+
"""
|
|
29
45
|
url = "{0}/{1}".format(self.baseurl, "signin")
|
|
30
46
|
signin_req = RequestFactory.Auth.signin_req(auth_req)
|
|
31
47
|
server_response = self.parent_srv.session.post(
|
|
@@ -50,13 +66,18 @@ class Auth(Endpoint):
|
|
|
50
66
|
logger.info("Signed into {0} as user with id {1}".format(self.parent_srv.server_address, user_id))
|
|
51
67
|
return Auth.contextmgr(self.sign_out)
|
|
52
68
|
|
|
69
|
+
# We use the same request that username/password login uses for all auth types.
|
|
70
|
+
# The distinct methods are mostly useful for explicitly showing api version support for each auth type
|
|
53
71
|
@api(version="3.6")
|
|
54
|
-
def sign_in_with_personal_access_token(self, auth_req):
|
|
55
|
-
|
|
72
|
+
def sign_in_with_personal_access_token(self, auth_req: "Credentials") -> contextmgr:
|
|
73
|
+
return self.sign_in(auth_req)
|
|
74
|
+
|
|
75
|
+
@api(version="3.17")
|
|
76
|
+
def sign_in_with_json_web_token(self, auth_req: "Credentials") -> contextmgr:
|
|
56
77
|
return self.sign_in(auth_req)
|
|
57
78
|
|
|
58
79
|
@api(version="2.0")
|
|
59
|
-
def sign_out(self):
|
|
80
|
+
def sign_out(self) -> None:
|
|
60
81
|
url = "{0}/{1}".format(self.baseurl, "signout")
|
|
61
82
|
# If there are no auth tokens you're already signed out. No-op
|
|
62
83
|
if not self.parent_srv.is_signed_in():
|
|
@@ -66,7 +87,7 @@ class Auth(Endpoint):
|
|
|
66
87
|
logger.info("Signed out")
|
|
67
88
|
|
|
68
89
|
@api(version="2.6")
|
|
69
|
-
def switch_site(self, site_item):
|
|
90
|
+
def switch_site(self, site_item: "SiteItem") -> contextmgr:
|
|
70
91
|
url = "{0}/{1}".format(self.baseurl, "switchSite")
|
|
71
92
|
switch_req = RequestFactory.Auth.switch_req(site_item.content_url)
|
|
72
93
|
try:
|
|
@@ -87,7 +108,7 @@ class Auth(Endpoint):
|
|
|
87
108
|
return Auth.contextmgr(self.sign_out)
|
|
88
109
|
|
|
89
110
|
@api(version="3.10")
|
|
90
|
-
def revoke_all_server_admin_tokens(self):
|
|
111
|
+
def revoke_all_server_admin_tokens(self) -> None:
|
|
91
112
|
url = "{0}/{1}".format(self.baseurl, "revokeAllServerAdminTokens")
|
|
92
113
|
self.post_request(url, "")
|
|
93
114
|
logger.info("Revoked all tokens for all server admins")
|
|
@@ -82,14 +82,17 @@ class Groups(QuerysetEndpoint):
|
|
|
82
82
|
)
|
|
83
83
|
group_item.minimum_site_role = default_site_role
|
|
84
84
|
|
|
85
|
+
url = "{0}/{1}".format(self.baseurl, group_item.id)
|
|
86
|
+
|
|
85
87
|
if not group_item.id:
|
|
86
88
|
error = "Group item missing ID."
|
|
87
89
|
raise MissingRequiredFieldError(error)
|
|
88
90
|
if as_job and (group_item.domain_name is None or group_item.domain_name == "local"):
|
|
89
91
|
error = "Local groups cannot be updated asynchronously."
|
|
90
92
|
raise ValueError(error)
|
|
93
|
+
elif as_job:
|
|
94
|
+
url = "?".join([url, "asJob=True"])
|
|
91
95
|
|
|
92
|
-
url = "{0}/{1}".format(self.baseurl, group_item.id)
|
|
93
96
|
update_req = RequestFactory.Group.update_req(group_item, None)
|
|
94
97
|
server_response = self.put_request(url, update_req)
|
|
95
98
|
logger.info("Updated group item (ID: {0})".format(group_item.id))
|
|
@@ -63,6 +63,8 @@ class Projects(QuerysetEndpoint):
|
|
|
63
63
|
def create(self, project_item: ProjectItem, samples: bool = False) -> ProjectItem:
|
|
64
64
|
params = {"params": {RequestOptions.Field.PublishSamples: samples}}
|
|
65
65
|
url = self.baseurl
|
|
66
|
+
if project_item._samples:
|
|
67
|
+
url = "{0}?publishSamples={1}".format(self.baseurl, project_item._samples)
|
|
66
68
|
create_req = RequestFactory.Project.create_req(project_item)
|
|
67
69
|
server_response = self.post_request(url, create_req, XML_CONTENT_TYPE, params)
|
|
68
70
|
new_project = ProjectItem.from_response(server_response.content, self.parent_srv.namespace)[0]
|
|
@@ -51,6 +51,17 @@ class Tasks(Endpoint):
|
|
|
51
51
|
server_response = self.get_request(url)
|
|
52
52
|
return TaskItem.from_response(server_response.content, self.parent_srv.namespace)[0]
|
|
53
53
|
|
|
54
|
+
@api(version="3.19")
|
|
55
|
+
def create(self, extract_item: TaskItem) -> TaskItem:
|
|
56
|
+
if not extract_item:
|
|
57
|
+
error = "No extract refresh provided"
|
|
58
|
+
raise ValueError(error)
|
|
59
|
+
logger.info("Creating an extract refresh ({})".format(extract_item))
|
|
60
|
+
url = "{0}/{1}".format(self.baseurl, self.__normalize_task_type(TaskItem.Type.ExtractRefresh))
|
|
61
|
+
create_req = RequestFactory.Task.create_extract_req(extract_item)
|
|
62
|
+
server_response = self.post_request(url, create_req)
|
|
63
|
+
return server_response.content
|
|
64
|
+
|
|
54
65
|
@api(version="2.6")
|
|
55
66
|
def run(self, task_item):
|
|
56
67
|
if not task_item.id:
|
|
@@ -11,7 +11,11 @@ class Filter(object):
|
|
|
11
11
|
def __str__(self):
|
|
12
12
|
value_string = str(self._value)
|
|
13
13
|
if isinstance(self._value, list):
|
|
14
|
-
|
|
14
|
+
# this should turn the string representation of the list
|
|
15
|
+
# from ['<string1>', '<string2>', ...]
|
|
16
|
+
# to [<string1>,<string2>]
|
|
17
|
+
# so effectively, remove any spaces between "," and "'" and then remove all "'"
|
|
18
|
+
value_string = value_string.replace(", '", ",'").replace("'", "")
|
|
15
19
|
return "{0}:{1}:{2}".format(self.field, self.operator, value_string)
|
|
16
20
|
|
|
17
21
|
@property
|
|
@@ -1028,6 +1028,34 @@ class TaskRequest(object):
|
|
|
1028
1028
|
# Send an empty tsRequest
|
|
1029
1029
|
pass
|
|
1030
1030
|
|
|
1031
|
+
@_tsrequest_wrapped
|
|
1032
|
+
def create_extract_req(self, xml_request: ET.Element, extract_item: "TaskItem") -> bytes:
|
|
1033
|
+
extract_element = ET.SubElement(xml_request, "extractRefresh")
|
|
1034
|
+
|
|
1035
|
+
# Schedule attributes
|
|
1036
|
+
schedule_element = ET.SubElement(xml_request, "schedule")
|
|
1037
|
+
|
|
1038
|
+
interval_item = extract_item.schedule_item.interval_item
|
|
1039
|
+
schedule_element.attrib["frequency"] = interval_item._frequency
|
|
1040
|
+
frequency_element = ET.SubElement(schedule_element, "frequencyDetails")
|
|
1041
|
+
frequency_element.attrib["start"] = str(interval_item.start_time)
|
|
1042
|
+
if hasattr(interval_item, "end_time") and interval_item.end_time is not None:
|
|
1043
|
+
frequency_element.attrib["end"] = str(interval_item.end_time)
|
|
1044
|
+
if hasattr(interval_item, "interval") and interval_item.interval:
|
|
1045
|
+
intervals_element = ET.SubElement(frequency_element, "intervals")
|
|
1046
|
+
for interval in interval_item._interval_type_pairs():
|
|
1047
|
+
expression, value = interval
|
|
1048
|
+
single_interval_element = ET.SubElement(intervals_element, "interval")
|
|
1049
|
+
single_interval_element.attrib[expression] = value
|
|
1050
|
+
|
|
1051
|
+
# Main attributes
|
|
1052
|
+
extract_element.attrib["type"] = extract_item.task_type
|
|
1053
|
+
|
|
1054
|
+
target_element = ET.SubElement(extract_element, extract_item.target.type)
|
|
1055
|
+
target_element.attrib["id"] = extract_item.target.id
|
|
1056
|
+
|
|
1057
|
+
return ET.tostring(xml_request)
|
|
1058
|
+
|
|
1031
1059
|
|
|
1032
1060
|
class SubscriptionRequest(object):
|
|
1033
1061
|
@_tsrequest_wrapped
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: tableauserverclient
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.28
|
|
4
4
|
Summary: A Python module for working with the Tableau Server REST API.
|
|
5
5
|
Author-email: Tableau <github@tableau.com>
|
|
6
6
|
License: The MIT License (MIT)
|
|
@@ -28,26 +28,28 @@ License: The MIT License (MIT)
|
|
|
28
28
|
Project-URL: repository, https://github.com/tableau/server-client-python
|
|
29
29
|
Classifier: Programming Language :: Python
|
|
30
30
|
Classifier: Programming Language :: Python :: 3
|
|
31
|
-
Classifier: Programming Language :: Python :: 3.7
|
|
32
31
|
Classifier: Programming Language :: Python :: 3.8
|
|
33
32
|
Classifier: Programming Language :: Python :: 3.9
|
|
34
33
|
Classifier: Programming Language :: Python :: 3.10
|
|
34
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
35
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
35
36
|
Requires-Python: >=3.7
|
|
36
37
|
Description-Content-Type: text/markdown
|
|
37
38
|
License-File: LICENSE
|
|
38
39
|
License-File: LICENSE.versioneer
|
|
39
|
-
Requires-Dist: defusedxml
|
|
40
|
-
Requires-Dist: packaging
|
|
41
|
-
Requires-Dist: requests
|
|
42
|
-
Requires-Dist: urllib3
|
|
40
|
+
Requires-Dist: defusedxml >=0.7.1
|
|
41
|
+
Requires-Dist: packaging >=23.1
|
|
42
|
+
Requires-Dist: requests >=2.31
|
|
43
|
+
Requires-Dist: urllib3 ==2.0.6
|
|
43
44
|
Provides-Extra: test
|
|
44
45
|
Requires-Dist: argparse ; extra == 'test'
|
|
45
|
-
Requires-Dist: black ; extra == 'test'
|
|
46
|
+
Requires-Dist: black ==23.7 ; extra == 'test'
|
|
46
47
|
Requires-Dist: mock ; extra == 'test'
|
|
47
|
-
Requires-Dist: mypy ; extra == 'test'
|
|
48
|
-
Requires-Dist: pytest
|
|
48
|
+
Requires-Dist: mypy ==1.4 ; extra == 'test'
|
|
49
|
+
Requires-Dist: pytest >=7.0 ; extra == 'test'
|
|
50
|
+
Requires-Dist: pytest-cov ; extra == 'test'
|
|
49
51
|
Requires-Dist: pytest-subtests ; extra == 'test'
|
|
50
|
-
Requires-Dist: requests-mock
|
|
52
|
+
Requires-Dist: requests-mock <2.0,>=1.0 ; extra == 'test'
|
|
51
53
|
|
|
52
54
|
# Tableau Server Client (Python)
|
|
53
55
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
tableauserverclient/__init__.py,sha256=
|
|
2
|
-
tableauserverclient/_version.py,sha256=
|
|
1
|
+
tableauserverclient/__init__.py,sha256=hDjLTdwXPmQj4BQBRdUcnP7XdhT7apJ_c7JAPyyYZ7Y,1096
|
|
2
|
+
tableauserverclient/_version.py,sha256=77BR3Uhg7xOImjTULb4qcvv7VjeMtNO9xpnQ-eW_gLU,496
|
|
3
3
|
tableauserverclient/config.py,sha256=u9YnTDv0XnFR0sUY6AdeSuP5Zi2WKmcgJGGdehuaoO0,429
|
|
4
4
|
tableauserverclient/datetime_helpers.py,sha256=_-gWz5I2_KHT5AzW_boD8meH6loTTKdK-_62h1MA6ko,884
|
|
5
5
|
tableauserverclient/exponential_backoff.py,sha256=HtAfbbVnYtiOe2_ZzKqZmsml40EDZBaC3bttif5qeG8,1474
|
|
@@ -7,58 +7,58 @@ tableauserverclient/filesys_helpers.py,sha256=hosTm9fpc9B9_VCDcAuyHA0A-f-MWs9_2u
|
|
|
7
7
|
tableauserverclient/namespace.py,sha256=i0o0T0xO0vd1RX98o54xmIrqCkeVfhtQOGDMGRx_F_o,971
|
|
8
8
|
tableauserverclient/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
9
9
|
tableauserverclient/helpers/__init__.py,sha256=llpqF9zV5dsP5hQt8dyop33Op5OzGmxW0BZibaSlCcM,23
|
|
10
|
-
tableauserverclient/helpers/logging.py,sha256=
|
|
10
|
+
tableauserverclient/helpers/logging.py,sha256=5q_oR3wERHVXFXY6XDnLYML5-HdAPJTmqhH9IZg4VfY,113
|
|
11
11
|
tableauserverclient/helpers/strings.py,sha256=dnfm_2s75WvXnkcU8JFGRlLbSZdarRPyHpRYOi19APs,1682
|
|
12
|
-
tableauserverclient/models/__init__.py,sha256=
|
|
13
|
-
tableauserverclient/models/column_item.py,sha256=
|
|
14
|
-
tableauserverclient/models/connection_credentials.py,sha256=
|
|
12
|
+
tableauserverclient/models/__init__.py,sha256=NfVfRDeU8b6zTQ7wzkorhvuGIPabym8lXvNiyEX_AVg,1620
|
|
13
|
+
tableauserverclient/models/column_item.py,sha256=gV2r7xOVmcn9UnMXFOe9_ORZ85oha1KtIH-crKUhgN4,1972
|
|
14
|
+
tableauserverclient/models/connection_credentials.py,sha256=8Wa8B_-cB3INFUup-Pyd5znsUD5opgYYH5TfipCzKTU,1559
|
|
15
15
|
tableauserverclient/models/connection_item.py,sha256=BiLrjWY42EtkAyh2_3juo31rYW9YZN1e3uOXMXIaslY,4743
|
|
16
|
-
tableauserverclient/models/custom_view_item.py,sha256=
|
|
17
|
-
tableauserverclient/models/data_acceleration_report_item.py,sha256=
|
|
16
|
+
tableauserverclient/models/custom_view_item.py,sha256=Gr2lYgBU1zUfCoaXHhqTzWDspmL33UqOxlt48Y8yaGg,5782
|
|
17
|
+
tableauserverclient/models/data_acceleration_report_item.py,sha256=5Z18-fppR_lnAyPKHwxi4gOP6kqcYX3Q3RdwiD4Zy94,3402
|
|
18
18
|
tableauserverclient/models/data_alert_item.py,sha256=sJpncsKY1BY-tFJKDpX7xaHy6aGvELWrorsILJxr3lI,6458
|
|
19
19
|
tableauserverclient/models/database_item.py,sha256=SAwoxsgeowwFN20zGt3-226kJabk0M2tqbVLQthvmRs,8043
|
|
20
|
-
tableauserverclient/models/datasource_item.py,sha256=
|
|
20
|
+
tableauserverclient/models/datasource_item.py,sha256=ZZZvYfzg6gD7DlZWzfEJ3VBQBMYADJ9GeoWV02F7Z8E,11944
|
|
21
21
|
tableauserverclient/models/dqw_item.py,sha256=MFpxSP6vSzpjh5GLNrom--Sbi8iLwuGLuAda8KHiIa8,3718
|
|
22
22
|
tableauserverclient/models/exceptions.py,sha256=pQu5DS4jNMT9A0wEBWv2vANAQU1vgNpFatVr8sGE4zk,105
|
|
23
23
|
tableauserverclient/models/favorites_item.py,sha256=AfQOraRaZ_c2lY9XzxOeeg0N89WHOOYW3CREsCuACNs,3140
|
|
24
24
|
tableauserverclient/models/fileupload_item.py,sha256=tx3LfgRxVqeHGpCN6kTDPkdBY5i1H-u1RVaPf0hQx_4,750
|
|
25
25
|
tableauserverclient/models/flow_item.py,sha256=rPIVDe8_tHied8TDRiGpg2gyTyQWlNiGb3vGhqF9YJw,7320
|
|
26
26
|
tableauserverclient/models/flow_run_item.py,sha256=pwJNz0m7l--Sb6z0o83ebWfAmTVFYSr-0apMxHWt0Vs,3139
|
|
27
|
-
tableauserverclient/models/group_item.py,sha256=
|
|
28
|
-
tableauserverclient/models/interval_item.py,sha256=
|
|
29
|
-
tableauserverclient/models/job_item.py,sha256=
|
|
30
|
-
tableauserverclient/models/metric_item.py,sha256=
|
|
31
|
-
tableauserverclient/models/pagination_item.py,sha256=
|
|
32
|
-
tableauserverclient/models/permissions_item.py,sha256=
|
|
33
|
-
tableauserverclient/models/project_item.py,sha256=
|
|
27
|
+
tableauserverclient/models/group_item.py,sha256=1KP_KmIG1veJJGyte82aFvMAiU_tvzYtaP2vLEReLoo,3621
|
|
28
|
+
tableauserverclient/models/interval_item.py,sha256=h0mAFnR3rOj9nNOT237sPHQrdkN3NyonnGX10Chbx9k,5747
|
|
29
|
+
tableauserverclient/models/job_item.py,sha256=PMt7G2qu8WAxe-b3f_0BtQ9JcCSvk-g5L5EcOUpYFCY,8619
|
|
30
|
+
tableauserverclient/models/metric_item.py,sha256=Zrzi_Un43p2jzE_4OhetxhjfeSUYzotMfm8Hjd5WOhI,5397
|
|
31
|
+
tableauserverclient/models/pagination_item.py,sha256=Hdr2EIKWkXfrjWOr-Ao_vzQTWB2akUfxxtaupFKLrlQ,1432
|
|
32
|
+
tableauserverclient/models/permissions_item.py,sha256=2WlJOc1Vxkxl-WnAkFaacWsGxUXU9_d85AetSKrKwP0,3731
|
|
33
|
+
tableauserverclient/models/project_item.py,sha256=Mf5maEdKJqk5ojhT_DNmLqL50Ib6u1OKYEDq0oJpeGs,7056
|
|
34
34
|
tableauserverclient/models/property_decorators.py,sha256=eXaYxzXYuHdftlcnqSQOzHYM7OAilETWK8Td2Dtmmuc,4726
|
|
35
35
|
tableauserverclient/models/reference_item.py,sha256=HddG1loGNJU7gB7hBccCjnhagnSEbk4_wY2kuPbNhRQ,534
|
|
36
36
|
tableauserverclient/models/revision_item.py,sha256=fLkcScAgBBiVMCyDPk4aboyZNxrykIavzJP2vkn6Rq0,2787
|
|
37
|
-
tableauserverclient/models/schedule_item.py,sha256=
|
|
38
|
-
tableauserverclient/models/server_info_item.py,sha256=
|
|
39
|
-
tableauserverclient/models/site_item.py,sha256
|
|
40
|
-
tableauserverclient/models/subscription_item.py,sha256=
|
|
41
|
-
tableauserverclient/models/table_item.py,sha256=
|
|
42
|
-
tableauserverclient/models/tableau_auth.py,sha256=
|
|
37
|
+
tableauserverclient/models/schedule_item.py,sha256=AmodNmh9iKdlGzyEm0pRjdy8-yFSXsIe7xf0Y6oVFVc,10569
|
|
38
|
+
tableauserverclient/models/server_info_item.py,sha256=pR_fqqPuiBwpLn0wr4rQ4vxK7gxGJVTtaswzwjslheE,1880
|
|
39
|
+
tableauserverclient/models/site_item.py,sha256=xvXpsR0eEz2ypS-94KJTMS-gusHV1bLomKIhWX7GXrU,42256
|
|
40
|
+
tableauserverclient/models/subscription_item.py,sha256=XkQiAi_gWPBnxtTaB8TgrFa-IDVDtai9H00Ilay0T64,4744
|
|
41
|
+
tableauserverclient/models/table_item.py,sha256=WgXrHCgmA5djpA7k2tNuZ8A3PPK6GEKfj9RQZ27RsNk,4583
|
|
42
|
+
tableauserverclient/models/tableau_auth.py,sha256=TdkOtRnNRi4p0w_WhBsWqUunNVG9nxKl6NPO2AQ08zU,3723
|
|
43
43
|
tableauserverclient/models/tableau_types.py,sha256=1iq1034K1W9ugLAxON_t8n2UxSouiWV_ZEwoHiNM94c,918
|
|
44
44
|
tableauserverclient/models/tag_item.py,sha256=mVfJGZG8PspPM8hBxX38heEQ_Rnp5sSwfwWdLNA-UV0,619
|
|
45
45
|
tableauserverclient/models/target.py,sha256=dVc1SHwo9ZASR8250MhAPODXX_G5UqA4BnK8hykRE6E,263
|
|
46
46
|
tableauserverclient/models/task_item.py,sha256=0DSOZ3aQ6nppD-zVeeK-GKdAxLE0-d-sSazXs7ybH6Q,3466
|
|
47
|
-
tableauserverclient/models/user_item.py,sha256=
|
|
48
|
-
tableauserverclient/models/view_item.py,sha256=
|
|
47
|
+
tableauserverclient/models/user_item.py,sha256=vaQD3nvU7bJVD6t0nkWQFse8UDz8HTp8wh_6WmCjKtM,15776
|
|
48
|
+
tableauserverclient/models/view_item.py,sha256=7OLTLpLXDiYAWi7Tc6vSCkh2Krl7-cvKUwA7iMWZspQ,6777
|
|
49
49
|
tableauserverclient/models/webhook_item.py,sha256=LLf2HQ2Y50Rw-c4dSYyv6MXLbXdij9Iyy261gu9zpv4,2650
|
|
50
|
-
tableauserverclient/models/workbook_item.py,sha256=
|
|
50
|
+
tableauserverclient/models/workbook_item.py,sha256=x-qRFLAkVKQzd-PFYTkfuzYBkMcW3EOvc6Zx-iVWa3U,12974
|
|
51
51
|
tableauserverclient/server/__init__.py,sha256=ZyvucBvBQMPyTVW7oDHl4W9NWuaSVSMfN9cTcSQRmKw,406
|
|
52
52
|
tableauserverclient/server/exceptions.py,sha256=l-O4lcoEeXJC7fLWUanIcZM_Mf8m54uK3NQuKNj3RCg,183
|
|
53
|
-
tableauserverclient/server/filter.py,sha256=
|
|
53
|
+
tableauserverclient/server/filter.py,sha256=WZ_dIBuADRZf8VTYcRgn1rulSGUOJq8_uUltq05KkRI,1119
|
|
54
54
|
tableauserverclient/server/pager.py,sha256=rd6rKkoTxP0u3RiOZ3HY9oWKyOcf8aowbHPcs-Ul4D0,2725
|
|
55
55
|
tableauserverclient/server/query.py,sha256=qMweo-N5P_V9z2Or4u_QrStaBbGL6HOg4Y4EDg8uh44,5735
|
|
56
|
-
tableauserverclient/server/request_factory.py,sha256=
|
|
57
|
-
tableauserverclient/server/request_options.py,sha256=
|
|
56
|
+
tableauserverclient/server/request_factory.py,sha256=u8h2EtGKBAN5ELR9Cg_v3bSKvRsMmy4IXVkYp4OZqzQ,59190
|
|
57
|
+
tableauserverclient/server/request_options.py,sha256=xilsnYTsNObCZfwB5ydfzYq7XBkhpvIMWHM67yWQSKY,7105
|
|
58
58
|
tableauserverclient/server/server.py,sha256=LhbQOk-lvIBAOF5tTAghYNPFsKJN4Z95SJbuHLAxdKo,8401
|
|
59
59
|
tableauserverclient/server/sort.py,sha256=ikndqXW2r2FeacJzybC2TVcJGn4ktviWgXwPyK-AX-0,208
|
|
60
60
|
tableauserverclient/server/endpoint/__init__.py,sha256=9KGDtgBWlWsWbBQvQV2cbIU-VmHmMqcgtSM7PonpIzg,1141
|
|
61
|
-
tableauserverclient/server/endpoint/auth_endpoint.py,sha256=
|
|
61
|
+
tableauserverclient/server/endpoint/auth_endpoint.py,sha256=EOGGlGHWUZRN0SFBlYnEWUSwCH1lrB0Zfv4VWdd7HQs,5139
|
|
62
62
|
tableauserverclient/server/endpoint/custom_views_endpoint.py,sha256=SShsI8TnDe3tPXCrCsjs3Oy5Ym4j-QrcDXUfZ7rF9Y4,4542
|
|
63
63
|
tableauserverclient/server/endpoint/data_acceleration_report_endpoint.py,sha256=nfC2gXoCke-YXGTiMWGDRBK_lDlLa9Y6hts7w3Zs8cI,1170
|
|
64
64
|
tableauserverclient/server/endpoint/data_alert_endpoint.py,sha256=c6-ICGRVDRQN7ClAgCeJsk6JK4HyBvtQGQVLOzNc4eo,5358
|
|
@@ -68,30 +68,30 @@ tableauserverclient/server/endpoint/default_permissions_endpoint.py,sha256=HQSYP
|
|
|
68
68
|
tableauserverclient/server/endpoint/dqw_endpoint.py,sha256=TvzjonvIiGtp4EisoBKms1lHOkVTjagQACw6unyY9_8,2418
|
|
69
69
|
tableauserverclient/server/endpoint/endpoint.py,sha256=IZtHZia7aSr2sc1iV8bdtg39kX-IBDsXLoAxKa3y5v8,14425
|
|
70
70
|
tableauserverclient/server/endpoint/exceptions.py,sha256=fh4fFYasqiKd3EPTxriVsmLkRL24wz9UvX94BMRfyLY,2534
|
|
71
|
-
tableauserverclient/server/endpoint/favorites_endpoint.py,sha256=
|
|
71
|
+
tableauserverclient/server/endpoint/favorites_endpoint.py,sha256=D0MCco9kxaeCShfWOnVt3UpttJRgczJmJKXb3w0jpw4,6701
|
|
72
72
|
tableauserverclient/server/endpoint/fileuploads_endpoint.py,sha256=fh2xH6a8mMcBI14QzodWPBMabK1_9SMDbzZbawz-ZJc,2553
|
|
73
73
|
tableauserverclient/server/endpoint/flow_runs_endpoint.py,sha256=1vwkOrb574natWl-njFOij8xaV32e9RU3-rFbu4bML0,3338
|
|
74
74
|
tableauserverclient/server/endpoint/flows_endpoint.py,sha256=97S15UatgSzdw22Q5ZfhtlVVTvahp7fAtrXt7L28OWg,12898
|
|
75
|
-
tableauserverclient/server/endpoint/groups_endpoint.py,sha256=
|
|
75
|
+
tableauserverclient/server/endpoint/groups_endpoint.py,sha256=_aSTVy7m3NXSEqgC0cPfJt6KOaPoWprxzz0MD8CsiiY,6640
|
|
76
76
|
tableauserverclient/server/endpoint/jobs_endpoint.py,sha256=P5Hdv1hsNVxd5KdrcNCfR9ZtJ7v3UgrfATCBItVdAxY,3239
|
|
77
77
|
tableauserverclient/server/endpoint/metadata_endpoint.py,sha256=AKnmRNj9U85p__igiuY_vhhipsxNXpQ_9zzNUtTuU9o,5203
|
|
78
78
|
tableauserverclient/server/endpoint/metrics_endpoint.py,sha256=pW7ZOmRrsk_d1afITrQKhYdDDo3zqw1Vq-FnhBnSM24,3264
|
|
79
79
|
tableauserverclient/server/endpoint/permissions_endpoint.py,sha256=K-AZ1VPTHfiuyEwLo4qQLVTacwYFgNEGrYpCtgO9nmY,3879
|
|
80
|
-
tableauserverclient/server/endpoint/projects_endpoint.py,sha256=
|
|
80
|
+
tableauserverclient/server/endpoint/projects_endpoint.py,sha256=cbW-VTtrG1dt2kQy5vGCmurB8w3ethuNQvyaWViSpIE,7323
|
|
81
81
|
tableauserverclient/server/endpoint/resource_tagger.py,sha256=NJ64WySE7RWIR3JNltyWbErwwdaw9L_Wi7TLWdNas_4,2248
|
|
82
82
|
tableauserverclient/server/endpoint/schedules_endpoint.py,sha256=VKlAqTqMtxkvkG2UgZQ6VrBkiAgpjgffRZFzdzV9LtM,6462
|
|
83
83
|
tableauserverclient/server/endpoint/server_info_endpoint.py,sha256=4TtCc7oIp6iEuiZYGC_1NDIBsWetKk7b0rNemoA2VXI,1453
|
|
84
84
|
tableauserverclient/server/endpoint/sites_endpoint.py,sha256=lMeVXxm1k32HZK84u7aTys9hUQekb4PE1hlhKFxaZ8c,6694
|
|
85
85
|
tableauserverclient/server/endpoint/subscriptions_endpoint.py,sha256=mMo9M6DF6tAZIab6UY8f_duETezELl9VXEYs5ocAcGY,3280
|
|
86
86
|
tableauserverclient/server/endpoint/tables_endpoint.py,sha256=OJQIarL-IC9mjeu1jfNh9B3UEkB41O51Q53TQNeSJ78,5376
|
|
87
|
-
tableauserverclient/server/endpoint/tasks_endpoint.py,sha256=
|
|
87
|
+
tableauserverclient/server/endpoint/tasks_endpoint.py,sha256=jHz-d3q-hoxmv9Xg2qPAOzAz9mv0ahHtPSW8IXon0sw,3707
|
|
88
88
|
tableauserverclient/server/endpoint/users_endpoint.py,sha256=QRoApMyP53nF-AqvC7oLHNcT4VJE8s5ykjUnI5ojmPY,7274
|
|
89
89
|
tableauserverclient/server/endpoint/views_endpoint.py,sha256=GIYPftL5B0YUOb_SisFtfLP0LPIAbbUv24XCi15UH_M,7118
|
|
90
90
|
tableauserverclient/server/endpoint/webhooks_endpoint.py,sha256=-HsbAuKECNcx5EZkqp097PfGHLCNwPRnxbrdzreTpnM,2835
|
|
91
91
|
tableauserverclient/server/endpoint/workbooks_endpoint.py,sha256=65Zv-b0yd4yuh1JAoqbhNlEJM6k2LD6nh1nPQGTdKRc,21734
|
|
92
|
-
tableauserverclient-0.
|
|
93
|
-
tableauserverclient-0.
|
|
94
|
-
tableauserverclient-0.
|
|
95
|
-
tableauserverclient-0.
|
|
96
|
-
tableauserverclient-0.
|
|
97
|
-
tableauserverclient-0.
|
|
92
|
+
tableauserverclient-0.28.dist-info/LICENSE,sha256=MMkY7MguOb4L-WCmmqrVcwg2iwSGaz-RfAMFvXRXwsQ,1074
|
|
93
|
+
tableauserverclient-0.28.dist-info/LICENSE.versioneer,sha256=OYaGozOXk7bUNSm1z577iDYpti8a40XIqqR4lyQ47D8,334
|
|
94
|
+
tableauserverclient-0.28.dist-info/METADATA,sha256=0oM0-poO__vHSlu02Lfa93Lv8lRqYsNn5RI5B6UIRvI,4073
|
|
95
|
+
tableauserverclient-0.28.dist-info/WHEEL,sha256=yQN5g4mg4AybRjkgi-9yy4iQEFibGQmlz78Pik5Or-A,92
|
|
96
|
+
tableauserverclient-0.28.dist-info/top_level.txt,sha256=kBnL39G2RlGqxJSsShDBWG4WZ3NFcWJkv1EGiOfZh4Q,20
|
|
97
|
+
tableauserverclient-0.28.dist-info/RECORD,,
|
|
File without changes
|
{tableauserverclient-0.26.dist-info → tableauserverclient-0.28.dist-info}/LICENSE.versioneer
RENAMED
|
File without changes
|
|
File without changes
|