castor-extractor 0.24.9__py3-none-any.whl → 0.24.10__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.
- CHANGELOG.md +4 -0
- castor_extractor/visualization/tableau/client/client_metadata_api.py +46 -8
- castor_extractor/visualization/tableau/client/client_metadata_api_test.py +81 -1
- {castor_extractor-0.24.9.dist-info → castor_extractor-0.24.10.dist-info}/METADATA +5 -1
- {castor_extractor-0.24.9.dist-info → castor_extractor-0.24.10.dist-info}/RECORD +8 -8
- {castor_extractor-0.24.9.dist-info → castor_extractor-0.24.10.dist-info}/LICENCE +0 -0
- {castor_extractor-0.24.9.dist-info → castor_extractor-0.24.10.dist-info}/WHEEL +0 -0
- {castor_extractor-0.24.9.dist-info → castor_extractor-0.24.10.dist-info}/entry_points.txt +0 -0
CHANGELOG.md
CHANGED
|
@@ -29,24 +29,62 @@ _RETRY_BASE_MS = 10_000
|
|
|
29
29
|
_RETRY_COUNT = 4
|
|
30
30
|
|
|
31
31
|
|
|
32
|
+
def _is_timeout(error: dict) -> bool:
|
|
33
|
+
error_message = error.get("message")
|
|
34
|
+
return error_message == _TIMEOUT_MESSAGE
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def _is_warning(error: dict) -> bool:
|
|
38
|
+
extensions = error.get("extensions")
|
|
39
|
+
if not extensions:
|
|
40
|
+
return False
|
|
41
|
+
|
|
42
|
+
severity = extensions.get("severity")
|
|
43
|
+
if not severity:
|
|
44
|
+
return False
|
|
45
|
+
|
|
46
|
+
return severity.lower() == "warning"
|
|
47
|
+
|
|
48
|
+
|
|
32
49
|
def _check_errors(answer: dict) -> None:
|
|
33
50
|
"""
|
|
34
|
-
|
|
51
|
+
Handle errors in graphql response:
|
|
35
52
|
- return None when there's no errors in the answer
|
|
36
|
-
- TableauApiTimeout if any of the errors is a timeout
|
|
37
|
-
- TableauApiError
|
|
53
|
+
- raise TableauApiTimeout if any of the errors is a timeout
|
|
54
|
+
- else raise TableauApiError if any of the errors is critical
|
|
55
|
+
- return None otherwise
|
|
56
|
+
More info about Tableau errors:
|
|
57
|
+
https://help.tableau.com/current/api/metadata_api/en-us/docs/meta_api_errors.html#other-errors
|
|
38
58
|
"""
|
|
39
59
|
if "errors" not in answer:
|
|
40
60
|
return
|
|
41
61
|
|
|
42
62
|
errors = answer["errors"]
|
|
43
63
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
# we need specific handling for timeout issues (retry strategy)
|
|
47
|
-
raise TableauApiTimeout(errors)
|
|
64
|
+
has_timeout_errors = False
|
|
65
|
+
has_critical_errors = False
|
|
48
66
|
|
|
49
|
-
|
|
67
|
+
for error in errors:
|
|
68
|
+
if _is_timeout(error):
|
|
69
|
+
has_timeout_errors = True
|
|
70
|
+
continue
|
|
71
|
+
|
|
72
|
+
if _is_warning(error):
|
|
73
|
+
# in this case, the answer contains the data anyway
|
|
74
|
+
# just display the warning
|
|
75
|
+
logger.warning(error)
|
|
76
|
+
continue
|
|
77
|
+
|
|
78
|
+
# at this point, it's not a timeout error
|
|
79
|
+
# besides, it's not a warning (severity is either "error" or Unknown)
|
|
80
|
+
has_critical_errors = True
|
|
81
|
+
|
|
82
|
+
if has_timeout_errors:
|
|
83
|
+
raise TableauApiTimeout(errors)
|
|
84
|
+
if has_critical_errors:
|
|
85
|
+
raise TableauApiError(errors)
|
|
86
|
+
|
|
87
|
+
return None
|
|
50
88
|
|
|
51
89
|
|
|
52
90
|
def gql_query_scroll(
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
import pytest
|
|
2
|
+
|
|
3
|
+
from .client_metadata_api import _TIMEOUT_MESSAGE, _check_errors, _deduplicate
|
|
4
|
+
from .errors import TableauApiError, TableauApiTimeout
|
|
2
5
|
|
|
3
6
|
|
|
4
7
|
def test__deduplicate():
|
|
@@ -29,3 +32,80 @@ def test__deduplicate():
|
|
|
29
32
|
assert len(deduplicated) == 5
|
|
30
33
|
deduplicated_keys = {item["id"] for item in deduplicated}
|
|
31
34
|
assert deduplicated_keys == {1, 2, 3, 4, 5}
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def _timeout_error():
|
|
38
|
+
return {"message": _TIMEOUT_MESSAGE}
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def _critical_error():
|
|
42
|
+
return {
|
|
43
|
+
"message": "critical error",
|
|
44
|
+
"extensions": {"severity": "Error"},
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def _unknown_severity_error():
|
|
49
|
+
return {
|
|
50
|
+
"message": "unknown severity error",
|
|
51
|
+
"extensions": {"severity": None},
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def _warning():
|
|
56
|
+
return {
|
|
57
|
+
"message": "critical error",
|
|
58
|
+
"extensions": {"severity": "Warning"},
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def test__check_errors():
|
|
63
|
+
answer = {"data": []} # no errors
|
|
64
|
+
assert _check_errors(answer) is None
|
|
65
|
+
|
|
66
|
+
# only warnings
|
|
67
|
+
answer = {
|
|
68
|
+
"data": [],
|
|
69
|
+
"errors": [
|
|
70
|
+
_warning(),
|
|
71
|
+
_warning(),
|
|
72
|
+
_warning(),
|
|
73
|
+
],
|
|
74
|
+
}
|
|
75
|
+
assert _check_errors(answer) is None
|
|
76
|
+
|
|
77
|
+
# timeout issues should be prio (because they can be retried)
|
|
78
|
+
answer = {
|
|
79
|
+
"data": [],
|
|
80
|
+
"errors": [
|
|
81
|
+
_warning(),
|
|
82
|
+
_critical_error(),
|
|
83
|
+
_timeout_error(),
|
|
84
|
+
_warning(),
|
|
85
|
+
],
|
|
86
|
+
}
|
|
87
|
+
with pytest.raises(TableauApiTimeout):
|
|
88
|
+
_check_errors(answer)
|
|
89
|
+
|
|
90
|
+
# expect critical error
|
|
91
|
+
answer = {
|
|
92
|
+
"data": [],
|
|
93
|
+
"errors": [
|
|
94
|
+
_warning(),
|
|
95
|
+
_warning(),
|
|
96
|
+
_critical_error(),
|
|
97
|
+
],
|
|
98
|
+
}
|
|
99
|
+
with pytest.raises(TableauApiError):
|
|
100
|
+
_check_errors(answer)
|
|
101
|
+
|
|
102
|
+
# unknown severity is considered as critical
|
|
103
|
+
answer = {
|
|
104
|
+
"data": [],
|
|
105
|
+
"errors": [
|
|
106
|
+
_unknown_severity_error(),
|
|
107
|
+
_warning(),
|
|
108
|
+
],
|
|
109
|
+
}
|
|
110
|
+
with pytest.raises(TableauApiError):
|
|
111
|
+
_check_errors(answer)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: castor-extractor
|
|
3
|
-
Version: 0.24.
|
|
3
|
+
Version: 0.24.10
|
|
4
4
|
Summary: Extract your metadata assets.
|
|
5
5
|
Home-page: https://www.castordoc.com/
|
|
6
6
|
License: EULA
|
|
@@ -210,6 +210,10 @@ For any questions or bug report, contact us at [support@castordoc.com](mailto:su
|
|
|
210
210
|
|
|
211
211
|
# Changelog
|
|
212
212
|
|
|
213
|
+
## 0.24.10 - 2025-04-30
|
|
214
|
+
|
|
215
|
+
* Tableau - skip warnings instead of raising an error
|
|
216
|
+
|
|
213
217
|
## 0.24.9 - 2025-04-16
|
|
214
218
|
|
|
215
219
|
* Introduce API client for **Coalesce**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
CHANGELOG.md,sha256=
|
|
1
|
+
CHANGELOG.md,sha256=PDbRWM3MtvskjUAjZXatnsZwB2M22ufediw5J3GETVo,16901
|
|
2
2
|
Dockerfile,sha256=xQ05-CFfGShT3oUqaiumaldwA288dj9Yb_pxofQpufg,301
|
|
3
3
|
DockerfileUsage.md,sha256=2hkJQF-5JuuzfPZ7IOxgM6QgIQW7l-9oRMFVwyXC4gE,998
|
|
4
4
|
LICENCE,sha256=sL-IGa4hweyya1HgzMskrRdybbIa2cktzxb5qmUgDg8,8254
|
|
@@ -276,8 +276,8 @@ castor_extractor/visualization/tableau/__init__.py,sha256=eFI_1hjdkxyUiAYiy3szwy
|
|
|
276
276
|
castor_extractor/visualization/tableau/assets.py,sha256=HbCRd8VCj1WBEeqg9jwnygnT7xOFJ6PQD7Lq7sV-XR0,635
|
|
277
277
|
castor_extractor/visualization/tableau/client/__init__.py,sha256=P8RKFKOC63WkH5hdEytJOwHS9vzQ8GXreLfXZetmMP8,78
|
|
278
278
|
castor_extractor/visualization/tableau/client/client.py,sha256=zzqhzIqKyJygo4ZNGk6cZh0e6Z9R1W5T0P9un52KC1M,7626
|
|
279
|
-
castor_extractor/visualization/tableau/client/client_metadata_api.py,sha256=
|
|
280
|
-
castor_extractor/visualization/tableau/client/client_metadata_api_test.py,sha256=
|
|
279
|
+
castor_extractor/visualization/tableau/client/client_metadata_api.py,sha256=ryRq4_qUok8vvWGhj5CNWXtwR2JlUsu1qjsov2KhQTE,6286
|
|
280
|
+
castor_extractor/visualization/tableau/client/client_metadata_api_test.py,sha256=rikyQKDLFYHLJhHJTF3LwWhKJ80svtTsYp5n7n9oTU8,2665
|
|
281
281
|
castor_extractor/visualization/tableau/client/client_rest_api.py,sha256=x4dNw4PPJdalTlGowwkANwqiS2ZhGxzpQytkHq3KbpY,3988
|
|
282
282
|
castor_extractor/visualization/tableau/client/client_tsc.py,sha256=VI_PJyd1ty3HSYXHHQjshmG2ziowIbrwJRonRPCHbks,1820
|
|
283
283
|
castor_extractor/visualization/tableau/client/credentials.py,sha256=uQICIgeXmLZfOroTgZt7PuKNKTyqQllRGSTcOmIfrKU,1893
|
|
@@ -416,8 +416,8 @@ castor_extractor/warehouse/sqlserver/queries/table.sql,sha256=kbBQP-TdG5px1IVgyx
|
|
|
416
416
|
castor_extractor/warehouse/sqlserver/queries/user.sql,sha256=gOrZsMVypusR2dc4vwVs4E1a-CliRsr_UjnD2EbXs-A,94
|
|
417
417
|
castor_extractor/warehouse/sqlserver/query.py,sha256=g0hPT-RmeGi2DyenAi3o72cTlQsLToXIFYojqc8E5fQ,533
|
|
418
418
|
castor_extractor/warehouse/synapse/queries/column.sql,sha256=lNcFoIW3Y0PFOqoOzJEXmPvZvfAsY0AP63Mu2LuPzPo,1351
|
|
419
|
-
castor_extractor-0.24.
|
|
420
|
-
castor_extractor-0.24.
|
|
421
|
-
castor_extractor-0.24.
|
|
422
|
-
castor_extractor-0.24.
|
|
423
|
-
castor_extractor-0.24.
|
|
419
|
+
castor_extractor-0.24.10.dist-info/LICENCE,sha256=sL-IGa4hweyya1HgzMskrRdybbIa2cktzxb5qmUgDg8,8254
|
|
420
|
+
castor_extractor-0.24.10.dist-info/METADATA,sha256=yB6KyU6Enp2Tcnmr4StHAmsKhwj3Fh0l7EnxaPQgM5c,24066
|
|
421
|
+
castor_extractor-0.24.10.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
|
|
422
|
+
castor_extractor-0.24.10.dist-info/entry_points.txt,sha256=FQNShG4w4nRO95_bZnagh7FQ2oiZ-40bdt8ZdTW1-uI,1731
|
|
423
|
+
castor_extractor-0.24.10.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|