castor-extractor 0.23.3__py3-none-any.whl → 0.24.0__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.

Potentially problematic release.


This version of castor-extractor might be problematic. Click here for more details.

Files changed (43) hide show
  1. CHANGELOG.md +4 -0
  2. castor_extractor/knowledge/confluence/client/client.py +0 -13
  3. castor_extractor/knowledge/confluence/client/endpoints.py +1 -1
  4. {castor_extractor-0.23.3.dist-info → castor_extractor-0.24.0.dist-info}/METADATA +5 -1
  5. {castor_extractor-0.23.3.dist-info → castor_extractor-0.24.0.dist-info}/RECORD +8 -43
  6. castor_extractor/visualization/tableau/__init__.py +0 -3
  7. castor_extractor/visualization/tableau/assets.py +0 -49
  8. castor_extractor/visualization/tableau/client/__init__.py +0 -2
  9. castor_extractor/visualization/tableau/client/client.py +0 -229
  10. castor_extractor/visualization/tableau/client/client_utils.py +0 -75
  11. castor_extractor/visualization/tableau/client/credentials.py +0 -104
  12. castor_extractor/visualization/tableau/client/project.py +0 -28
  13. castor_extractor/visualization/tableau/client/safe_mode.py +0 -70
  14. castor_extractor/visualization/tableau/constants.py +0 -9
  15. castor_extractor/visualization/tableau/errors.py +0 -5
  16. castor_extractor/visualization/tableau/extract.py +0 -121
  17. castor_extractor/visualization/tableau/gql_fields.py +0 -249
  18. castor_extractor/visualization/tableau/tests/__init__.py +0 -0
  19. castor_extractor/visualization/tableau/tests/unit/__init__.py +0 -0
  20. castor_extractor/visualization/tableau/tests/unit/assets/graphql/metadata/metadata_1_get.json +0 -15
  21. castor_extractor/visualization/tableau/tests/unit/assets/graphql/metadata/metadata_2_get.json +0 -15
  22. castor_extractor/visualization/tableau/tests/unit/assets/rest_api/auth.xml +0 -7
  23. castor_extractor/visualization/tableau/tests/unit/assets/rest_api/project_get.xml +0 -9
  24. castor_extractor/visualization/tableau/tests/unit/assets/rest_api/user_get.xml +0 -8
  25. castor_extractor/visualization/tableau/tests/unit/assets/rest_api/view_get_usage.xml +0 -24
  26. castor_extractor/visualization/tableau/tests/unit/assets/rest_api/workbook_get.xml +0 -19
  27. castor_extractor/visualization/tableau/tests/unit/graphql/__init__.py +0 -0
  28. castor_extractor/visualization/tableau/tests/unit/graphql/paginated_object_test.py +0 -63
  29. castor_extractor/visualization/tableau/tests/unit/rest_api/__init__.py +0 -0
  30. castor_extractor/visualization/tableau/tests/unit/rest_api/auth_test.py +0 -39
  31. castor_extractor/visualization/tableau/tests/unit/rest_api/credentials_test.py +0 -13
  32. castor_extractor/visualization/tableau/tests/unit/rest_api/projects_test.py +0 -59
  33. castor_extractor/visualization/tableau/tests/unit/rest_api/usages_test.py +0 -49
  34. castor_extractor/visualization/tableau/tests/unit/rest_api/users_test.py +0 -52
  35. castor_extractor/visualization/tableau/tests/unit/rest_api/workbooks_test.py +0 -60
  36. castor_extractor/visualization/tableau/tests/unit/utils/__init__.py +0 -1
  37. castor_extractor/visualization/tableau/tests/unit/utils/env_key.py +0 -6
  38. castor_extractor/visualization/tableau/tsc_fields.py +0 -46
  39. castor_extractor/visualization/tableau/types.py +0 -11
  40. castor_extractor/visualization/tableau/usage.py +0 -14
  41. {castor_extractor-0.23.3.dist-info → castor_extractor-0.24.0.dist-info}/LICENCE +0 -0
  42. {castor_extractor-0.23.3.dist-info → castor_extractor-0.24.0.dist-info}/WHEEL +0 -0
  43. {castor_extractor-0.23.3.dist-info → castor_extractor-0.24.0.dist-info}/entry_points.txt +0 -0
@@ -1,70 +0,0 @@
1
- import logging
2
-
3
- import tableauserverclient as TSC # type: ignore
4
-
5
- from ....utils import SerializedAsset
6
- from ..assets import TableauAsset
7
- from ..constants import SAFE_MODE_PAGE_SIZE
8
- from ..errors import TableauErrorCode
9
- from ..types import PageReturn, ServerResponseError
10
- from ..usage import compute_usage_views
11
- from .client_utils import extract_asset
12
-
13
- logger = logging.getLogger(__name__)
14
-
15
-
16
- def _paginated_option(page_number: int) -> TSC.RequestOptions:
17
- """Set up the Paginated option for TSC.RequestOptions"""
18
- return TSC.RequestOptions(
19
- pagesize=SAFE_MODE_PAGE_SIZE,
20
- pagenumber=page_number,
21
- )
22
-
23
-
24
- def _next_usage_page(client, page_number: int) -> PageReturn:
25
- """
26
- Request views per page
27
- return Usages | ServerResponseError | TableauErrorCode
28
- """
29
- options = _paginated_option(page_number)
30
- try:
31
- all_usages_items, _ = client._server.views.get(options, usage=True)
32
- return all_usages_items, None
33
-
34
- except ServerResponseError as error:
35
- expected = TableauErrorCode.PAGE_NUMBER_NOT_FOUND
36
- if error.code == expected.value:
37
- return None, expected
38
- raise error
39
-
40
- except ServerResponseError as error:
41
- return None, error
42
-
43
-
44
- def safe_mode_fetch_usage(client) -> SerializedAsset:
45
- """
46
- Iterate throught each page
47
- Returns computed usages when page number is not found
48
- Log errors if ServerResponseError is return
49
- """
50
- list_usages: list[dict] = []
51
- page_number: int = 0
52
-
53
- while True:
54
- page_number += 1
55
- usages, error = _next_usage_page(client, page_number)
56
- if error == TableauErrorCode.PAGE_NUMBER_NOT_FOUND:
57
- return compute_usage_views(list_usages)
58
-
59
- if error:
60
- logger.warning(error)
61
- client.errors.append(str(error))
62
- continue
63
-
64
- if not usages:
65
- continue
66
-
67
- new_usages = [
68
- extract_asset(usage, TableauAsset.USAGE) for usage in usages
69
- ]
70
- list_usages.extend(new_usages)
@@ -1,9 +0,0 @@
1
- # tableau
2
- TABLEAU_SERVER_VERSION = "3.5"
3
-
4
- # pagination
5
- PAGE_SIZE = 100
6
-
7
- # safe mode
8
- SAFE_MODE_PAGE_SIZE = 1
9
- SAFE_MODE = False
@@ -1,5 +0,0 @@
1
- from enum import Enum
2
-
3
-
4
- class TableauErrorCode(Enum):
5
- PAGE_NUMBER_NOT_FOUND = "400006"
@@ -1,121 +0,0 @@
1
- import logging
2
- from collections.abc import Iterable
3
-
4
- from ...utils import (
5
- OUTPUT_DIR,
6
- current_timestamp,
7
- deep_serialize,
8
- from_env,
9
- get_output_filename,
10
- write_errors_logs,
11
- write_json,
12
- write_summary,
13
- )
14
- from .assets import TableauAsset
15
- from .client import ApiClient as Client
16
-
17
- logger = logging.getLogger(__name__)
18
-
19
-
20
- def iterate_all_data(
21
- client: Client,
22
- ) -> Iterable[tuple[TableauAsset, list]]:
23
- """Iterate over the extracted Data from Tableau"""
24
-
25
- logger.info("Extracting USER from Tableau API")
26
- yield TableauAsset.USER, deep_serialize(client.fetch(TableauAsset.USER))
27
-
28
- logger.info("Extracting WORKBOOK from Tableau API")
29
- yield (
30
- TableauAsset.WORKBOOK,
31
- deep_serialize(
32
- client.fetch(TableauAsset.WORKBOOK),
33
- ),
34
- )
35
-
36
- logger.info("Extracting DASHBOARD from Tableau API")
37
- yield (
38
- TableauAsset.DASHBOARD,
39
- deep_serialize(
40
- client.fetch(TableauAsset.DASHBOARD),
41
- ),
42
- )
43
-
44
- logger.info("Extracting PUBLISHED DATASOURCE from Tableau API")
45
- yield (
46
- TableauAsset.PUBLISHED_DATASOURCE,
47
- deep_serialize(
48
- client.fetch(TableauAsset.PUBLISHED_DATASOURCE),
49
- ),
50
- )
51
-
52
- logger.info("Extracting PROJECT from Tableau API")
53
- yield (
54
- TableauAsset.PROJECT,
55
- deep_serialize(
56
- client.fetch(TableauAsset.PROJECT),
57
- ),
58
- )
59
-
60
- logger.info("Extracting USAGE from Tableau API")
61
- yield TableauAsset.USAGE, deep_serialize(client.fetch(TableauAsset.USAGE))
62
-
63
- logger.info("Extracting WORKBOOK_TO_DATASOURCE from Tableau API")
64
- yield (
65
- TableauAsset.WORKBOOK_TO_DATASOURCE,
66
- deep_serialize(
67
- client.fetch(TableauAsset.WORKBOOK_TO_DATASOURCE),
68
- ),
69
- )
70
-
71
- logger.info("Extracting DATASOURCE from Tableau API")
72
- yield (
73
- TableauAsset.DATASOURCE,
74
- deep_serialize(
75
- client.fetch(TableauAsset.DATASOURCE),
76
- ),
77
- )
78
-
79
- logger.info("Extracting CUSTOM_SQL_TABLE from Tableau API")
80
- yield (
81
- TableauAsset.CUSTOM_SQL_TABLE,
82
- deep_serialize(
83
- client.fetch(TableauAsset.CUSTOM_SQL_TABLE),
84
- ),
85
- )
86
-
87
- logger.info("Extracting CUSTOM_SQL_QUERY from Tableau API")
88
- yield (
89
- TableauAsset.CUSTOM_SQL_QUERY,
90
- deep_serialize(
91
- client.fetch(TableauAsset.CUSTOM_SQL_QUERY),
92
- ),
93
- )
94
-
95
- logger.info("Extracting FIELD from Tableau API")
96
- yield TableauAsset.FIELD, deep_serialize(client.fetch(TableauAsset.FIELD))
97
-
98
-
99
- def extract_all(client: Client, **kwargs: str) -> None:
100
- """
101
- Extract Data from tableau
102
- Store data locally in files under the output_directory
103
- If errors from Tableau's API are catch store them locally in file under the output_directory
104
- """
105
- output_directory = kwargs.get("output_directory") or from_env(OUTPUT_DIR)
106
-
107
- timestamp = current_timestamp()
108
-
109
- for key, data in iterate_all_data(client):
110
- filename = get_output_filename(key.value, output_directory, timestamp)
111
- write_json(filename, data)
112
-
113
- write_summary(
114
- output_directory,
115
- timestamp,
116
- base_url=client.base_url(),
117
- client_name=client.name(),
118
- )
119
-
120
- if client.errors:
121
- write_errors_logs(output_directory, timestamp, client.errors)
@@ -1,249 +0,0 @@
1
- # Fields which will be use for Tableau GraphQL API
2
- from enum import Enum
3
- from typing import Union
4
-
5
- from .assets import TableauAsset, TableauGraphqlAsset
6
-
7
- FIELDS = "fields"
8
- OBJECT_TYPE = "object_type"
9
-
10
-
11
- class GQLQueryFields(Enum):
12
- BIN_FIELDS: str = """
13
- datasource {
14
- ... on PublishedDatasource {
15
- name
16
- luid
17
- }
18
- }
19
- dataType
20
- description
21
- fields {
22
- id
23
- }
24
- folderName
25
- id
26
- name
27
- role
28
- """
29
-
30
- CALCULATED_FIELDS: str = """
31
- datasource {
32
- ... on PublishedDatasource {
33
- name
34
- luid
35
- }
36
- }
37
- fields {
38
- id
39
- }
40
- dataType
41
- description
42
- folderName
43
- id
44
- name
45
- role
46
-
47
- """
48
-
49
- COLUMN_FIELDS: str = """
50
- columns {
51
- id
52
- name
53
- table {
54
- ... on DatabaseTable {
55
- id
56
- description
57
- name
58
- fullName
59
- schema
60
- database {
61
- name
62
- luid
63
- }
64
- }
65
- }
66
-
67
- }
68
- datasource {
69
- ... on PublishedDatasource {
70
- name
71
- luid
72
- }
73
- }
74
- dataType
75
- description
76
- folderName
77
- id
78
- name
79
- role
80
- """
81
-
82
- CUSTOM_SQL_TABLE: str = """
83
- id
84
- name
85
- columns {
86
- referencedByFields {
87
- datasource {
88
- ... on PublishedDatasource {
89
- luid
90
- }
91
-
92
- ... on EmbeddedDatasource {
93
- id
94
- }
95
- }
96
- }
97
- }
98
- """
99
-
100
- CUSTOM_SQL_QUERY: str = """
101
- id
102
- name
103
- query
104
- database {
105
- name
106
- connectionType
107
- }
108
- tables {
109
- name
110
- }
111
- """
112
-
113
- DASHBOARDS: str = """
114
- id
115
- name
116
- path
117
- tags {
118
- name
119
- }
120
- workbook {
121
- luid # to retrieve the parent
122
- }
123
- """
124
-
125
- DATASOURCE: str = """
126
- ... on PublishedDatasource {
127
- luid
128
- }
129
- id
130
- name
131
- hasExtracts
132
- upstreamTables {
133
- id
134
- schema
135
- name
136
- fullName
137
- database {
138
- id
139
- name
140
- connectionType
141
- }
142
- }
143
- """
144
-
145
- GROUP_FIELDS: str = """
146
- datasource {
147
- ... on PublishedDatasource {
148
- name
149
- luid
150
- }
151
- }
152
- dataType
153
- description
154
- fields {
155
- id
156
- }
157
- folderName
158
- id
159
- name
160
- role
161
- """
162
-
163
- SHEET: str = """
164
- containedInDashboards {
165
- id
166
- }
167
- id
168
- index
169
- name
170
- upstreamFields{
171
- name
172
- }
173
- workbook {
174
- luid
175
- }
176
- """
177
-
178
- WORKBOOK_TO_DATASOURCE: str = """
179
- luid
180
- id
181
- embeddedDatasources {
182
- id
183
- name
184
- }
185
- upstreamDatasources {
186
- luid
187
- name
188
- }
189
- """
190
-
191
-
192
- QueryInfo = list[dict[str, Union[GQLQueryFields, TableauGraphqlAsset]]]
193
-
194
- QUERY_FIELDS: dict[TableauAsset, QueryInfo] = {
195
- TableauAsset.CUSTOM_SQL_TABLE: [
196
- {
197
- FIELDS: GQLQueryFields.CUSTOM_SQL_TABLE,
198
- OBJECT_TYPE: TableauGraphqlAsset.CUSTOM_SQL,
199
- },
200
- ],
201
- TableauAsset.CUSTOM_SQL_QUERY: [
202
- {
203
- FIELDS: GQLQueryFields.CUSTOM_SQL_QUERY,
204
- OBJECT_TYPE: TableauGraphqlAsset.CUSTOM_SQL,
205
- },
206
- ],
207
- TableauAsset.DASHBOARD: [
208
- {
209
- FIELDS: GQLQueryFields.DASHBOARDS,
210
- OBJECT_TYPE: TableauGraphqlAsset.DASHBOARD,
211
- },
212
- ],
213
- TableauAsset.DATASOURCE: [
214
- {
215
- FIELDS: GQLQueryFields.DATASOURCE,
216
- OBJECT_TYPE: TableauGraphqlAsset.DATASOURCE,
217
- },
218
- ],
219
- TableauAsset.FIELD: [
220
- {
221
- FIELDS: GQLQueryFields.BIN_FIELDS,
222
- OBJECT_TYPE: TableauGraphqlAsset.BIN_FIELD,
223
- },
224
- {
225
- FIELDS: GQLQueryFields.CALCULATED_FIELDS,
226
- OBJECT_TYPE: TableauGraphqlAsset.CALCULATED_FIELD,
227
- },
228
- {
229
- FIELDS: GQLQueryFields.COLUMN_FIELDS,
230
- OBJECT_TYPE: TableauGraphqlAsset.COLUMN_FIELD,
231
- },
232
- {
233
- FIELDS: GQLQueryFields.GROUP_FIELDS,
234
- OBJECT_TYPE: TableauGraphqlAsset.GROUP_FIELD,
235
- },
236
- ],
237
- TableauAsset.SHEET: [
238
- {
239
- FIELDS: GQLQueryFields.SHEET,
240
- OBJECT_TYPE: TableauGraphqlAsset.SHEETS,
241
- },
242
- ],
243
- TableauAsset.WORKBOOK_TO_DATASOURCE: [
244
- {
245
- FIELDS: GQLQueryFields.WORKBOOK_TO_DATASOURCE,
246
- OBJECT_TYPE: TableauGraphqlAsset.WORKBOOK_TO_DATASOURCE,
247
- },
248
- ],
249
- }
File without changes
@@ -1,15 +0,0 @@
1
- {
2
- "data": {
3
- "datasourcesConnection": {
4
- "pageInfo": {
5
- "hasNextPage": true,
6
- "endCursor": "eyJ0eXBlIjoiUHVibGlzaGVkRGF0YXNvdXJjZSIsInNjb3BlIjoic2l0ZXMvMSIsInNvcnRPcmRlclZhbHVlIjp7Imxhc3RJZCI6IjAwMzllNWQ1LTI1ZmEtMTk2Yi1jNjZlLWMwNjc1ODM5ZTBiMCJ9fQ=="
7
- },
8
- "nodes": [
9
- {
10
- "id": "0039e5d5-25fa-196b-c66e-c0675839e0b0"
11
- }
12
- ]
13
- }
14
- }
15
- }
@@ -1,15 +0,0 @@
1
- {
2
- "data": {
3
- "datasourcesConnection": {
4
- "pageInfo": {
5
- "hasNextPage": false,
6
- "endCursor": "eyJ0eXBlIjoiUHVibGlzaGVkRGF0YXNvdXJjZSIsInNjb3BlIjoic2l0ZXMvMSIsInNvcnRPcmRlclZhbHVlIjp7Imxhc3RJZCI6IjAwYjE5MWNlLTYwNTUtYWZmNS1lMjc1LWMyNjYxMGM4YzRkNiJ9fQ=="
7
- },
8
- "nodes": [
9
- {
10
- "id": "00b191ce-6055-aff5-e275-c26610c8c4d6"
11
- }
12
- ]
13
- }
14
- }
15
- }
@@ -1,7 +0,0 @@
1
- <?xml version='1.0' encoding='UTF-8'?>
2
- <tsResponse xmlns="http://tableau.com/api" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://tableau.com/api http://tableau.com/api/ts-api-2.3.xsd">
3
- <credentials token="eIX6mvFsqyansa4KqEI1UwOpS8ggRs2l">
4
- <site id="6b7179ba-b82b-4f0f-91ed-812074ac5da6" contentUrl="Samples" />
5
- <user id="1a96d216-e9b8-497b-a82a-0b899a965e01" />
6
- </credentials>
7
- </tsResponse>
@@ -1,9 +0,0 @@
1
- <?xml version='1.0' encoding='UTF-8'?>
2
- <tsResponse xmlns="http://tableau.com/api" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://tableau.com/api http://tableau.com/api/ts-api-2.3.xsd">
3
- <pagination pageNumber="1" pageSize="100" totalAvailable="3" />
4
- <projects>
5
- <project id="ee8c6e70-43b6-11e6-af4f-f7b0d8e20760" name="default" description="The default project that was automatically created by Tableau." contentPermissions="ManagedByOwner"><owner id="dd2239f6-ddf1-4107-981a-4cf94e415794" /></project>
6
- <project id="1d0304cd-3796-429f-b815-7258370b9b74" name="Tableau" description="" contentPermissions="ManagedByOwner"><owner id="2a47bbf8-8900-4ebb-b0a4-2723bd7c46c3" /></project>
7
- <project id="4cc52973-5e3a-4d1f-a4fb-5b5f73796edf" name="Tableau/Child_1" description="" contentPermissions="ManagedByOwner" parentProjectId="1d0304cd-3796-429f-b815-7258370b9b74"><owner id="dd2239f6-ddf1-4107-981a-4cf94e415794" /></project>
8
- </projects>
9
- </tsResponse>
@@ -1,8 +0,0 @@
1
- <?xml version='1.0' encoding='UTF-8'?>
2
- <tsResponse xmlns="http://tableau.com/api" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://tableau.com/api http://tableau.com/api/ts-api-2.3.xsd">
3
- <pagination pageNumber="1" pageSize="100" totalAvailable="2" />
4
- <users>
5
- <user id="dd2239f6-ddf1-4107-981a-4cf94e415794" name="alice" siteRole="Publisher" lastLogin="2016-08-16T23:17:06Z" externalAuthUserId="" fullName="alice cook" email="alicecook@test.com" />
6
- <user id="2a47bbf8-8900-4ebb-b0a4-2723bd7c46c3" name="Bob" siteRole="Interactor" externalAuthUserId="" fullName="Bob Smith" email="bob@test.com" />
7
- </users>
8
- </tsResponse>
@@ -1,24 +0,0 @@
1
- <?xml version='1.0' encoding='UTF-8'?>
2
- <tsResponse xmlns="http://tableau.com/api" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://tableau.com/api http://tableau.com/api/ts-api-2.3.xsd">
3
- <pagination pageNumber="1" pageSize="100" totalAvailable="3" />
4
- <views>
5
- <view id="d79634e1-6063-4ec9-95ff-50acbf609ff5" name="ENDANGERED SAFARI" contentUrl="SafariSample/sheets/ENDANGEREDSAFARI">
6
- <workbook id="3cc6cd06-89ce-4fdc-b935-5294135d6d42" />
7
- <owner id="5de011f8-5aa9-4d5b-b991-f462c8dd6bb7" />
8
- <tags />
9
- <usage totalViewCount="7" />
10
- </view>
11
- <view id="f79634e1-6063-4ec9-95ff-50acbf609ff5" name="ENDANGERED SAFARI" contentUrl="SafariSample/sheets/ENDANGEREDSAFARI">
12
- <workbook id="3cc6cd06-89ce-4fdc-b935-5294135d6d42" />
13
- <owner id="5de011f8-5aa9-4d5b-b991-f462c8dd6bb7" />
14
- <tags />
15
- <usage totalViewCount="4" />
16
- </view>
17
- <view id="fd252f73-593c-4c4e-8584-c032b8022adc" name="Overview" contentUrl="Superstore/sheets/Overview" createdAt="2002-05-30T09:00:00Z" updatedAt="2002-06-05T08:00:59Z" sheetType="story">
18
- <workbook id="6d13b0ca-043d-4d42-8c9d-3f3313ea3a00" />
19
- <owner id="5de011f8-5aa9-4d5b-b991-f462c8dd6bb7" />
20
- <tags />
21
- <usage totalViewCount="13" />
22
- </view>
23
- </views>
24
- </tsResponse>
@@ -1,19 +0,0 @@
1
- <?xml version='1.0' encoding='UTF-8'?>
2
- <tsResponse xmlns="http://tableau.com/api" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://tableau.com/api http://tableau.com/api/ts-api-2.3.xsd">
3
- <pagination pageNumber="1" pageSize="100" totalAvailable="2" />
4
- <workbooks>
5
- <workbook id="6d13b0ca-043d-4d42-8c9d-3f3313ea3a00" name="Superstore" description="description for Superstore" contentUrl="Superstore" webpageUrl="http://tableauserver/#/workbooks/1/views" showTabs="false" size="1" createdAt="1" updatedAt="1">
6
- <project id="ee8c6e70-43b6-11e6-af4f-f7b0d8e20760" name="default" />
7
- <owner id="5de011f8-5aa9-4d5b-b991-f462c8dd6bb7" />
8
- <tags />
9
- </workbook>
10
- <workbook id="3cc6cd06-89ce-4fdc-b935-5294135d6d42" name="SafariSample" description="description for SafariSample" contentUrl="SafariSample" webpageUrl="http://tableauserver/#/workbooks/2/views" showTabs="false" size="26" createdAt="1" updatedAt="1">
11
- <project id="ee8c6e70-43b6-11e6-af4f-f7b0d8e20760" name="default" />
12
- <owner id="5de011f8-5aa9-4d5b-b991-f462c8dd6bb7" />
13
- <tags>
14
- <tag label="Safari" />
15
- <tag label="Sample" />
16
- </tags>
17
- </workbook>
18
- </workbooks>
19
- </tsResponse>
@@ -1,63 +0,0 @@
1
- import os
2
- import unittest
3
- from unittest import mock
4
-
5
- import requests_mock # type: ignore
6
- import tableauserverclient as TSC # type: ignore
7
-
8
- from .....tableau import TableauAsset
9
- from ....client import ApiClient, get_paginated_objects
10
- from ....constants import TABLEAU_SERVER_VERSION
11
- from ..utils import KEYS
12
-
13
- TEST_ASSET_DIR = os.path.join(
14
- os.path.dirname(__file__),
15
- "../assets/graphql/metadata",
16
- )
17
-
18
- METADATA_1 = os.path.join(TEST_ASSET_DIR, "metadata_1_get.json")
19
- METADATA_2 = os.path.join(TEST_ASSET_DIR, "metadata_2_get.json")
20
-
21
-
22
- EXPECTED_PAGINATED = [
23
- {"id": "0039e5d5-25fa-196b-c66e-c0675839e0b0"},
24
- {"id": "00b191ce-6055-aff5-e275-c26610c8c4d6"},
25
- ]
26
-
27
-
28
- class PaginatedObjectTests(unittest.TestCase):
29
- @mock.patch.dict(os.environ, KEYS)
30
- def setUp(self):
31
- self._client = ApiClient()
32
- self._client._server = TSC.Server("http://test")
33
-
34
- # Fake signin
35
- self._client._server._site_id = "dad65087-b08b-4603-af4e-2887b8aafc67"
36
- self._client._server._auth_token = "j80k54ll2lfMZ0tv97mlPvvSCRyD0DOM"
37
- self._client._server.version = TABLEAU_SERVER_VERSION
38
-
39
- self.baseurl = self._client._server.metadata.baseurl
40
-
41
- def test_paginated_object_with_datasources(self):
42
- with open(METADATA_1, "rb") as f:
43
- response_1_json = f.read().decode()
44
-
45
- with open(METADATA_2, "rb") as f:
46
- response_2_json = f.read().decode()
47
-
48
- with requests_mock.mock() as m:
49
- m.post(
50
- self.baseurl,
51
- [
52
- {"text": response_1_json, "status_code": 200},
53
- {"text": response_2_json, "status_code": 200},
54
- ],
55
- )
56
-
57
- results = get_paginated_objects(
58
- self._client._server,
59
- TableauAsset.DATASOURCE,
60
- self._client._page_size,
61
- )
62
-
63
- self.assertEqual(results, EXPECTED_PAGINATED)
@@ -1,39 +0,0 @@
1
- import os.path
2
- import unittest
3
- from unittest import mock
4
-
5
- import requests_mock # type: ignore
6
-
7
- from ....client import ApiClient
8
- from ..utils import KEYS
9
-
10
- TEST_ASSET_DIR = os.path.join(os.path.dirname(__file__), "../assets/rest_api/")
11
-
12
- AUTH_XML = os.path.join(TEST_ASSET_DIR, "auth.xml")
13
-
14
-
15
- class AuthTests(unittest.TestCase):
16
- @mock.patch.dict(os.environ, KEYS)
17
- def setUp(self):
18
- self._client = ApiClient()
19
- self.baseurl = self._client._server.auth.baseurl
20
-
21
- def test_auth(self):
22
- with open(AUTH_XML, "rb") as f:
23
- response_xml = f.read().decode("utf-8")
24
- with requests_mock.mock() as m:
25
- m.post(self.baseurl + "/signin", text=response_xml)
26
- self._client.login()
27
-
28
- self.assertEqual(
29
- "eIX6mvFsqyansa4KqEI1UwOpS8ggRs2l",
30
- self._client._server.auth_token,
31
- )
32
- self.assertEqual(
33
- "6b7179ba-b82b-4f0f-91ed-812074ac5da6",
34
- self._client._server.site_id,
35
- )
36
- self.assertEqual(
37
- "1a96d216-e9b8-497b-a82a-0b899a965e01",
38
- self._client._server.user_id,
39
- )