tableauserverclient 0.33__py3-none-any.whl → 0.35__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- tableauserverclient/__init__.py +33 -23
- tableauserverclient/{_version.py → bin/_version.py} +3 -3
- tableauserverclient/config.py +5 -3
- tableauserverclient/models/column_item.py +1 -1
- tableauserverclient/models/connection_credentials.py +18 -2
- tableauserverclient/models/connection_item.py +44 -6
- tableauserverclient/models/custom_view_item.py +78 -11
- tableauserverclient/models/data_acceleration_report_item.py +2 -2
- tableauserverclient/models/data_alert_item.py +5 -5
- tableauserverclient/models/data_freshness_policy_item.py +6 -6
- tableauserverclient/models/database_item.py +3 -3
- tableauserverclient/models/datasource_item.py +10 -10
- tableauserverclient/models/dqw_item.py +1 -1
- tableauserverclient/models/favorites_item.py +5 -6
- tableauserverclient/models/fileupload_item.py +1 -1
- tableauserverclient/models/flow_item.py +54 -9
- tableauserverclient/models/flow_run_item.py +3 -3
- tableauserverclient/models/group_item.py +44 -4
- tableauserverclient/models/groupset_item.py +4 -4
- tableauserverclient/models/interval_item.py +9 -9
- tableauserverclient/models/job_item.py +73 -8
- tableauserverclient/models/linked_tasks_item.py +5 -5
- tableauserverclient/models/metric_item.py +5 -5
- tableauserverclient/models/pagination_item.py +1 -1
- tableauserverclient/models/permissions_item.py +12 -10
- tableauserverclient/models/project_item.py +73 -19
- tableauserverclient/models/property_decorators.py +12 -11
- tableauserverclient/models/reference_item.py +2 -2
- tableauserverclient/models/revision_item.py +3 -3
- tableauserverclient/models/schedule_item.py +2 -2
- tableauserverclient/models/server_info_item.py +26 -6
- tableauserverclient/models/site_item.py +69 -3
- tableauserverclient/models/subscription_item.py +3 -3
- tableauserverclient/models/table_item.py +1 -1
- tableauserverclient/models/tableau_auth.py +115 -5
- tableauserverclient/models/tableau_types.py +2 -2
- tableauserverclient/models/tag_item.py +3 -4
- tableauserverclient/models/task_item.py +34 -4
- tableauserverclient/models/user_item.py +47 -17
- tableauserverclient/models/view_item.py +66 -13
- tableauserverclient/models/virtual_connection_item.py +6 -5
- tableauserverclient/models/webhook_item.py +39 -6
- tableauserverclient/models/workbook_item.py +116 -13
- tableauserverclient/namespace.py +1 -1
- tableauserverclient/server/__init__.py +2 -1
- tableauserverclient/server/endpoint/auth_endpoint.py +69 -10
- tableauserverclient/server/endpoint/custom_views_endpoint.py +258 -29
- tableauserverclient/server/endpoint/data_acceleration_report_endpoint.py +2 -2
- tableauserverclient/server/endpoint/data_alert_endpoint.py +14 -14
- tableauserverclient/server/endpoint/databases_endpoint.py +13 -12
- tableauserverclient/server/endpoint/datasources_endpoint.py +61 -62
- tableauserverclient/server/endpoint/default_permissions_endpoint.py +19 -18
- tableauserverclient/server/endpoint/dqw_endpoint.py +9 -9
- tableauserverclient/server/endpoint/endpoint.py +19 -21
- tableauserverclient/server/endpoint/exceptions.py +23 -7
- tableauserverclient/server/endpoint/favorites_endpoint.py +31 -31
- tableauserverclient/server/endpoint/fileuploads_endpoint.py +9 -11
- tableauserverclient/server/endpoint/flow_runs_endpoint.py +15 -13
- tableauserverclient/server/endpoint/flow_task_endpoint.py +2 -2
- tableauserverclient/server/endpoint/flows_endpoint.py +344 -29
- tableauserverclient/server/endpoint/groups_endpoint.py +342 -27
- tableauserverclient/server/endpoint/groupsets_endpoint.py +2 -2
- tableauserverclient/server/endpoint/jobs_endpoint.py +116 -7
- tableauserverclient/server/endpoint/linked_tasks_endpoint.py +2 -2
- tableauserverclient/server/endpoint/metadata_endpoint.py +2 -2
- tableauserverclient/server/endpoint/metrics_endpoint.py +10 -10
- tableauserverclient/server/endpoint/permissions_endpoint.py +13 -15
- tableauserverclient/server/endpoint/projects_endpoint.py +681 -30
- tableauserverclient/server/endpoint/resource_tagger.py +14 -13
- tableauserverclient/server/endpoint/schedules_endpoint.py +17 -18
- tableauserverclient/server/endpoint/server_info_endpoint.py +40 -5
- tableauserverclient/server/endpoint/sites_endpoint.py +282 -17
- tableauserverclient/server/endpoint/subscriptions_endpoint.py +10 -10
- tableauserverclient/server/endpoint/tables_endpoint.py +15 -14
- tableauserverclient/server/endpoint/tasks_endpoint.py +86 -8
- tableauserverclient/server/endpoint/users_endpoint.py +366 -19
- tableauserverclient/server/endpoint/views_endpoint.py +262 -20
- tableauserverclient/server/endpoint/virtual_connections_endpoint.py +6 -5
- tableauserverclient/server/endpoint/webhooks_endpoint.py +88 -11
- tableauserverclient/server/endpoint/workbooks_endpoint.py +653 -65
- tableauserverclient/server/filter.py +2 -2
- tableauserverclient/server/pager.py +29 -6
- tableauserverclient/server/query.py +68 -19
- tableauserverclient/server/request_factory.py +57 -37
- tableauserverclient/server/request_options.py +243 -141
- tableauserverclient/server/server.py +76 -10
- tableauserverclient/server/sort.py +16 -2
- {tableauserverclient-0.33.dist-info → tableauserverclient-0.35.dist-info}/METADATA +7 -7
- tableauserverclient-0.35.dist-info/RECORD +106 -0
- {tableauserverclient-0.33.dist-info → tableauserverclient-0.35.dist-info}/WHEEL +1 -1
- tableauserverclient-0.33.dist-info/RECORD +0 -106
- {tableauserverclient-0.33.dist-info → tableauserverclient-0.35.dist-info}/LICENSE +0 -0
- {tableauserverclient-0.33.dist-info → tableauserverclient-0.35.dist-info}/LICENSE.versioneer +0 -0
- {tableauserverclient-0.33.dist-info → tableauserverclient-0.35.dist-info}/top_level.txt +0 -0
|
@@ -2,7 +2,7 @@ import copy
|
|
|
2
2
|
import datetime
|
|
3
3
|
import uuid
|
|
4
4
|
import xml.etree.ElementTree as ET
|
|
5
|
-
from typing import Callable,
|
|
5
|
+
from typing import Callable, Optional
|
|
6
6
|
|
|
7
7
|
from defusedxml.ElementTree import fromstring
|
|
8
8
|
|
|
@@ -20,8 +20,93 @@ from .view_item import ViewItem
|
|
|
20
20
|
from .data_freshness_policy_item import DataFreshnessPolicyItem
|
|
21
21
|
|
|
22
22
|
|
|
23
|
-
class WorkbookItem
|
|
24
|
-
|
|
23
|
+
class WorkbookItem:
|
|
24
|
+
"""
|
|
25
|
+
The workbook resources for Tableau are defined in the WorkbookItem class.
|
|
26
|
+
The class corresponds to the workbook resources you can access using the
|
|
27
|
+
Tableau REST API. Some workbook methods take an instance of the WorkbookItem
|
|
28
|
+
class as arguments. The workbook item specifies the project.
|
|
29
|
+
|
|
30
|
+
Parameters
|
|
31
|
+
----------
|
|
32
|
+
project_id : Optional[str], optional
|
|
33
|
+
The project ID for the workbook, by default None.
|
|
34
|
+
|
|
35
|
+
name : Optional[str], optional
|
|
36
|
+
The name of the workbook, by default None.
|
|
37
|
+
|
|
38
|
+
show_tabs : bool, optional
|
|
39
|
+
Determines whether the workbook shows tabs for the view.
|
|
40
|
+
|
|
41
|
+
Attributes
|
|
42
|
+
----------
|
|
43
|
+
connections : list[ConnectionItem]
|
|
44
|
+
The list of data connections (ConnectionItem) for the data sources used
|
|
45
|
+
by the workbook. You must first call the workbooks.populate_connections
|
|
46
|
+
method to access this data. See the ConnectionItem class.
|
|
47
|
+
|
|
48
|
+
content_url : Optional[str]
|
|
49
|
+
The name of the workbook as it appears in the URL.
|
|
50
|
+
|
|
51
|
+
created_at : Optional[datetime.datetime]
|
|
52
|
+
The date and time the workbook was created.
|
|
53
|
+
|
|
54
|
+
description : Optional[str]
|
|
55
|
+
User-defined description of the workbook.
|
|
56
|
+
|
|
57
|
+
id : Optional[str]
|
|
58
|
+
The identifier for the workbook. You need this value to query a specific
|
|
59
|
+
workbook or to delete a workbook with the get_by_id and delete methods.
|
|
60
|
+
|
|
61
|
+
owner_id : Optional[str]
|
|
62
|
+
The identifier for the owner (UserItem) of the workbook.
|
|
63
|
+
|
|
64
|
+
preview_image : bytes
|
|
65
|
+
The thumbnail image for the view. You must first call the
|
|
66
|
+
workbooks.populate_preview_image method to access this data.
|
|
67
|
+
|
|
68
|
+
project_name : Optional[str]
|
|
69
|
+
The name of the project that contains the workbook.
|
|
70
|
+
|
|
71
|
+
size: int
|
|
72
|
+
The size of the workbook in megabytes.
|
|
73
|
+
|
|
74
|
+
hidden_views: Optional[list[str]]
|
|
75
|
+
List of string names of views that need to be hidden when the workbook
|
|
76
|
+
is published.
|
|
77
|
+
|
|
78
|
+
tags: set[str]
|
|
79
|
+
The set of tags associated with the workbook.
|
|
80
|
+
|
|
81
|
+
updated_at : Optional[datetime.datetime]
|
|
82
|
+
The date and time the workbook was last updated.
|
|
83
|
+
|
|
84
|
+
views : list[ViewItem]
|
|
85
|
+
The list of views (ViewItem) for the workbook. You must first call the
|
|
86
|
+
workbooks.populate_views method to access this data. See the ViewItem
|
|
87
|
+
class.
|
|
88
|
+
|
|
89
|
+
web_page_url : Optional[str]
|
|
90
|
+
The full URL for the workbook.
|
|
91
|
+
|
|
92
|
+
Examples
|
|
93
|
+
--------
|
|
94
|
+
# creating a new instance of a WorkbookItem
|
|
95
|
+
>>> import tableauserverclient as TSC
|
|
96
|
+
|
|
97
|
+
>>> # Create new workbook_item with project id '3a8b6148-493c-11e6-a621-6f3499394a39'
|
|
98
|
+
|
|
99
|
+
>>> new_workbook = TSC.WorkbookItem('3a8b6148-493c-11e6-a621-6f3499394a39')
|
|
100
|
+
"""
|
|
101
|
+
|
|
102
|
+
def __init__(
|
|
103
|
+
self,
|
|
104
|
+
project_id: Optional[str] = None,
|
|
105
|
+
name: Optional[str] = None,
|
|
106
|
+
show_tabs: bool = False,
|
|
107
|
+
thumbnails_user_id: Optional[str] = None,
|
|
108
|
+
thumbnails_group_id: Optional[str] = None,
|
|
109
|
+
) -> None:
|
|
25
110
|
self._connections = None
|
|
26
111
|
self._content_url = None
|
|
27
112
|
self._webpage_url = None
|
|
@@ -35,15 +120,15 @@ class WorkbookItem(object):
|
|
|
35
120
|
self._revisions = None
|
|
36
121
|
self._size = None
|
|
37
122
|
self._updated_at = None
|
|
38
|
-
self._views: Optional[Callable[[],
|
|
123
|
+
self._views: Optional[Callable[[], list[ViewItem]]] = None
|
|
39
124
|
self.name = name
|
|
40
125
|
self._description = None
|
|
41
126
|
self.owner_id: Optional[str] = None
|
|
42
127
|
# workaround for Personal Space workbooks without a project
|
|
43
128
|
self.project_id: Optional[str] = project_id or uuid.uuid4().__str__()
|
|
44
129
|
self.show_tabs = show_tabs
|
|
45
|
-
self.hidden_views: Optional[
|
|
46
|
-
self.tags:
|
|
130
|
+
self.hidden_views: Optional[list[str]] = None
|
|
131
|
+
self.tags: set[str] = set()
|
|
47
132
|
self.data_acceleration_config = {
|
|
48
133
|
"acceleration_enabled": None,
|
|
49
134
|
"accelerate_now": None,
|
|
@@ -52,11 +137,13 @@ class WorkbookItem(object):
|
|
|
52
137
|
}
|
|
53
138
|
self.data_freshness_policy = None
|
|
54
139
|
self._permissions = None
|
|
140
|
+
self.thumbnails_user_id = thumbnails_user_id
|
|
141
|
+
self.thumbnails_group_id = thumbnails_group_id
|
|
55
142
|
|
|
56
143
|
return None
|
|
57
144
|
|
|
58
145
|
def __str__(self):
|
|
59
|
-
return "<WorkbookItem {
|
|
146
|
+
return "<WorkbookItem {} '{}' contentUrl='{}' project={}>".format(
|
|
60
147
|
self._id, self.name, self.content_url, self.project_id
|
|
61
148
|
)
|
|
62
149
|
|
|
@@ -64,14 +151,14 @@ class WorkbookItem(object):
|
|
|
64
151
|
return self.__str__() + " { " + ", ".join(" % s: % s" % item for item in vars(self).items()) + "}"
|
|
65
152
|
|
|
66
153
|
@property
|
|
67
|
-
def connections(self) ->
|
|
154
|
+
def connections(self) -> list[ConnectionItem]:
|
|
68
155
|
if self._connections is None:
|
|
69
156
|
error = "Workbook item must be populated with connections first."
|
|
70
157
|
raise UnpopulatedPropertyError(error)
|
|
71
158
|
return self._connections()
|
|
72
159
|
|
|
73
160
|
@property
|
|
74
|
-
def permissions(self) ->
|
|
161
|
+
def permissions(self) -> list[PermissionsRule]:
|
|
75
162
|
if self._permissions is None:
|
|
76
163
|
error = "Workbook item must be populated with permissions first."
|
|
77
164
|
raise UnpopulatedPropertyError(error)
|
|
@@ -152,7 +239,7 @@ class WorkbookItem(object):
|
|
|
152
239
|
return self._updated_at
|
|
153
240
|
|
|
154
241
|
@property
|
|
155
|
-
def views(self) ->
|
|
242
|
+
def views(self) -> list[ViewItem]:
|
|
156
243
|
# Views can be set in an initial workbook response OR by a call
|
|
157
244
|
# to Server. Without getting too fancy, I think we can rely on
|
|
158
245
|
# returning a list from the response, until they call
|
|
@@ -191,19 +278,35 @@ class WorkbookItem(object):
|
|
|
191
278
|
self._data_freshness_policy = value
|
|
192
279
|
|
|
193
280
|
@property
|
|
194
|
-
def revisions(self) ->
|
|
281
|
+
def revisions(self) -> list[RevisionItem]:
|
|
195
282
|
if self._revisions is None:
|
|
196
283
|
error = "Workbook item must be populated with revisions first."
|
|
197
284
|
raise UnpopulatedPropertyError(error)
|
|
198
285
|
return self._revisions()
|
|
199
286
|
|
|
287
|
+
@property
|
|
288
|
+
def thumbnails_user_id(self) -> Optional[str]:
|
|
289
|
+
return self._thumbnails_user_id
|
|
290
|
+
|
|
291
|
+
@thumbnails_user_id.setter
|
|
292
|
+
def thumbnails_user_id(self, value: str):
|
|
293
|
+
self._thumbnails_user_id = value
|
|
294
|
+
|
|
295
|
+
@property
|
|
296
|
+
def thumbnails_group_id(self) -> Optional[str]:
|
|
297
|
+
return self._thumbnails_group_id
|
|
298
|
+
|
|
299
|
+
@thumbnails_group_id.setter
|
|
300
|
+
def thumbnails_group_id(self, value: str):
|
|
301
|
+
self._thumbnails_group_id = value
|
|
302
|
+
|
|
200
303
|
def _set_connections(self, connections):
|
|
201
304
|
self._connections = connections
|
|
202
305
|
|
|
203
306
|
def _set_permissions(self, permissions):
|
|
204
307
|
self._permissions = permissions
|
|
205
308
|
|
|
206
|
-
def _set_views(self, views: Callable[[],
|
|
309
|
+
def _set_views(self, views: Callable[[], list[ViewItem]]) -> None:
|
|
207
310
|
self._views = views
|
|
208
311
|
|
|
209
312
|
def _set_pdf(self, pdf: Callable[[], bytes]) -> None:
|
|
@@ -316,7 +419,7 @@ class WorkbookItem(object):
|
|
|
316
419
|
self.data_freshness_policy = data_freshness_policy
|
|
317
420
|
|
|
318
421
|
@classmethod
|
|
319
|
-
def from_response(cls, resp: str, ns:
|
|
422
|
+
def from_response(cls, resp: str, ns: dict[str, str]) -> list["WorkbookItem"]:
|
|
320
423
|
all_workbook_items = list()
|
|
321
424
|
parsed_response = fromstring(resp)
|
|
322
425
|
all_workbook_xml = parsed_response.findall(".//t:workbook", namespaces=ns)
|
tableauserverclient/namespace.py
CHANGED
|
@@ -11,7 +11,7 @@ from tableauserverclient.server.filter import Filter
|
|
|
11
11
|
from tableauserverclient.server.sort import Sort
|
|
12
12
|
from tableauserverclient.server.server import Server
|
|
13
13
|
from tableauserverclient.server.pager import Pager
|
|
14
|
-
from tableauserverclient.server.endpoint.exceptions import NotSignedInError
|
|
14
|
+
from tableauserverclient.server.endpoint.exceptions import FailedSignInError, NotSignedInError
|
|
15
15
|
|
|
16
16
|
from tableauserverclient.server.endpoint import (
|
|
17
17
|
Auth,
|
|
@@ -57,6 +57,7 @@ __all__ = [
|
|
|
57
57
|
"Sort",
|
|
58
58
|
"Server",
|
|
59
59
|
"Pager",
|
|
60
|
+
"FailedSignInError",
|
|
60
61
|
"NotSignedInError",
|
|
61
62
|
"Auth",
|
|
62
63
|
"CustomViews",
|
|
@@ -16,7 +16,7 @@ if TYPE_CHECKING:
|
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
class Auth(Endpoint):
|
|
19
|
-
class contextmgr
|
|
19
|
+
class contextmgr:
|
|
20
20
|
def __init__(self, callback):
|
|
21
21
|
self._callback = callback
|
|
22
22
|
|
|
@@ -28,7 +28,7 @@ class Auth(Endpoint):
|
|
|
28
28
|
|
|
29
29
|
@property
|
|
30
30
|
def baseurl(self) -> str:
|
|
31
|
-
return "{
|
|
31
|
+
return f"{self.parent_srv.baseurl}/auth"
|
|
32
32
|
|
|
33
33
|
@api(version="2.0")
|
|
34
34
|
def sign_in(self, auth_req: "Credentials") -> contextmgr:
|
|
@@ -41,8 +41,32 @@ class Auth(Endpoint):
|
|
|
41
41
|
optionally a user_id to impersonate.
|
|
42
42
|
|
|
43
43
|
Creates a context manager that will sign out of the server upon exit.
|
|
44
|
+
|
|
45
|
+
Parameters
|
|
46
|
+
----------
|
|
47
|
+
auth_req : Credentials
|
|
48
|
+
The credentials object to use for signing in. Can be a TableauAuth,
|
|
49
|
+
PersonalAccessTokenAuth, or JWTAuth object.
|
|
50
|
+
|
|
51
|
+
Returns
|
|
52
|
+
-------
|
|
53
|
+
contextmgr
|
|
54
|
+
A context manager that will sign out of the server upon exit.
|
|
55
|
+
|
|
56
|
+
Examples
|
|
57
|
+
--------
|
|
58
|
+
>>> import tableauserverclient as TSC
|
|
59
|
+
|
|
60
|
+
>>> # create an auth object
|
|
61
|
+
>>> tableau_auth = TSC.TableauAuth('USERNAME', 'PASSWORD')
|
|
62
|
+
|
|
63
|
+
>>> # create an instance for your server
|
|
64
|
+
>>> server = TSC.Server('https://SERVER_URL')
|
|
65
|
+
|
|
66
|
+
>>> # call the sign-in method with the auth object
|
|
67
|
+
>>> server.auth.sign_in(tableau_auth)
|
|
44
68
|
"""
|
|
45
|
-
url = "{
|
|
69
|
+
url = f"{self.baseurl}/signin"
|
|
46
70
|
signin_req = RequestFactory.Auth.signin_req(auth_req)
|
|
47
71
|
server_response = self.parent_srv.session.post(
|
|
48
72
|
url, data=signin_req, **self.parent_srv.http_options, allow_redirects=False
|
|
@@ -60,25 +84,29 @@ class Auth(Endpoint):
|
|
|
60
84
|
self._check_status(server_response, url)
|
|
61
85
|
parsed_response = fromstring(server_response.content)
|
|
62
86
|
site_id = parsed_response.find(".//t:site", namespaces=self.parent_srv.namespace).get("id", None)
|
|
87
|
+
site_url = parsed_response.find(".//t:site", namespaces=self.parent_srv.namespace).get("contentUrl", None)
|
|
63
88
|
user_id = parsed_response.find(".//t:user", namespaces=self.parent_srv.namespace).get("id", None)
|
|
64
89
|
auth_token = parsed_response.find("t:credentials", namespaces=self.parent_srv.namespace).get("token", None)
|
|
65
|
-
self.parent_srv._set_auth(site_id, user_id, auth_token)
|
|
66
|
-
logger.info("Signed into {
|
|
90
|
+
self.parent_srv._set_auth(site_id, user_id, auth_token, site_url)
|
|
91
|
+
logger.info(f"Signed into {self.parent_srv.server_address} as user with id {user_id}")
|
|
67
92
|
return Auth.contextmgr(self.sign_out)
|
|
68
93
|
|
|
69
94
|
# We use the same request that username/password login uses for all auth types.
|
|
70
95
|
# The distinct methods are mostly useful for explicitly showing api version support for each auth type
|
|
71
96
|
@api(version="3.6")
|
|
72
97
|
def sign_in_with_personal_access_token(self, auth_req: "Credentials") -> contextmgr:
|
|
98
|
+
"""Passthrough to sign_in method"""
|
|
73
99
|
return self.sign_in(auth_req)
|
|
74
100
|
|
|
75
101
|
@api(version="3.17")
|
|
76
102
|
def sign_in_with_json_web_token(self, auth_req: "Credentials") -> contextmgr:
|
|
103
|
+
"""Passthrough to sign_in method"""
|
|
77
104
|
return self.sign_in(auth_req)
|
|
78
105
|
|
|
79
106
|
@api(version="2.0")
|
|
80
107
|
def sign_out(self) -> None:
|
|
81
|
-
|
|
108
|
+
"""Sign out of current session."""
|
|
109
|
+
url = f"{self.baseurl}/signout"
|
|
82
110
|
# If there are no auth tokens you're already signed out. No-op
|
|
83
111
|
if not self.parent_srv.is_signed_in():
|
|
84
112
|
return
|
|
@@ -88,7 +116,34 @@ class Auth(Endpoint):
|
|
|
88
116
|
|
|
89
117
|
@api(version="2.6")
|
|
90
118
|
def switch_site(self, site_item: "SiteItem") -> contextmgr:
|
|
91
|
-
|
|
119
|
+
"""
|
|
120
|
+
Switch to a different site on the server. This will sign out of the
|
|
121
|
+
current site and sign in to the new site. If used as a context manager,
|
|
122
|
+
will sign out of the new site upon exit.
|
|
123
|
+
|
|
124
|
+
Parameters
|
|
125
|
+
----------
|
|
126
|
+
site_item : SiteItem
|
|
127
|
+
The site to switch to.
|
|
128
|
+
|
|
129
|
+
Returns
|
|
130
|
+
-------
|
|
131
|
+
contextmgr
|
|
132
|
+
A context manager that will sign out of the new site upon exit.
|
|
133
|
+
|
|
134
|
+
Examples
|
|
135
|
+
--------
|
|
136
|
+
>>> import tableauserverclient as TSC
|
|
137
|
+
|
|
138
|
+
>>> # Find the site you want to switch to
|
|
139
|
+
>>> new_site = server.sites.get_by_id("9a8b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d")
|
|
140
|
+
>>> # switch to the new site
|
|
141
|
+
>>> with server.auth.switch_site(new_site):
|
|
142
|
+
>>> # do something on the new site
|
|
143
|
+
>>> pass
|
|
144
|
+
|
|
145
|
+
"""
|
|
146
|
+
url = f"{self.baseurl}/switchSite"
|
|
92
147
|
switch_req = RequestFactory.Auth.switch_req(site_item.content_url)
|
|
93
148
|
try:
|
|
94
149
|
server_response = self.post_request(url, switch_req)
|
|
@@ -101,14 +156,18 @@ class Auth(Endpoint):
|
|
|
101
156
|
self._check_status(server_response, url)
|
|
102
157
|
parsed_response = fromstring(server_response.content)
|
|
103
158
|
site_id = parsed_response.find(".//t:site", namespaces=self.parent_srv.namespace).get("id", None)
|
|
159
|
+
site_url = parsed_response.find(".//t:site", namespaces=self.parent_srv.namespace).get("contentUrl", None)
|
|
104
160
|
user_id = parsed_response.find(".//t:user", namespaces=self.parent_srv.namespace).get("id", None)
|
|
105
161
|
auth_token = parsed_response.find("t:credentials", namespaces=self.parent_srv.namespace).get("token", None)
|
|
106
|
-
self.parent_srv._set_auth(site_id, user_id, auth_token)
|
|
107
|
-
logger.info("Signed into {
|
|
162
|
+
self.parent_srv._set_auth(site_id, user_id, auth_token, site_url)
|
|
163
|
+
logger.info(f"Signed into {self.parent_srv.server_address} as user with id {user_id}")
|
|
108
164
|
return Auth.contextmgr(self.sign_out)
|
|
109
165
|
|
|
110
166
|
@api(version="3.10")
|
|
111
167
|
def revoke_all_server_admin_tokens(self) -> None:
|
|
112
|
-
|
|
168
|
+
"""
|
|
169
|
+
Revokes all personal access tokens for all server admins on the server.
|
|
170
|
+
"""
|
|
171
|
+
url = f"{self.baseurl}/revokeAllServerAdminTokens"
|
|
113
172
|
self.post_request(url, "")
|
|
114
173
|
logger.info("Revoked all tokens for all server admins")
|