castor-extractor 0.3.1__py3-none-any.whl → 0.3.5__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 +16 -0
- castor_extractor/commands/upload.py +3 -1
- castor_extractor/transformation/dbt/client/client.py +22 -4
- castor_extractor/uploader/constant.py +2 -0
- castor_extractor/visualization/tableau/gql_fields.py +3 -0
- castor_extractor/warehouse/snowflake/queries/query.sql +0 -1
- {castor_extractor-0.3.1.dist-info → castor_extractor-0.3.5.dist-info}/METADATA +1 -1
- {castor_extractor-0.3.1.dist-info → castor_extractor-0.3.5.dist-info}/RECORD +10 -10
- {castor_extractor-0.3.1.dist-info → castor_extractor-0.3.5.dist-info}/WHEEL +0 -0
- {castor_extractor-0.3.1.dist-info → castor_extractor-0.3.5.dist-info}/entry_points.txt +0 -0
CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.3.5 - 2023-04-07
|
|
4
|
+
|
|
5
|
+
* Extract metadata from successful dbt runs only
|
|
6
|
+
|
|
7
|
+
## 0.3.4 - 2023-04-05
|
|
8
|
+
|
|
9
|
+
* Enhance uploader to support `QUALITY` files
|
|
10
|
+
|
|
11
|
+
## 0.3.3 - 2023-04-04
|
|
12
|
+
|
|
13
|
+
* Tableau : Improve Table <> Datasource lineage
|
|
14
|
+
|
|
15
|
+
## 0.3.2 - 2023-04-04
|
|
16
|
+
|
|
17
|
+
* Allow COPY statements from Snowflake
|
|
18
|
+
|
|
3
19
|
## 0.3.1 - 2023-03-30
|
|
4
20
|
|
|
5
21
|
* Improved Field extraction in Tableau
|
|
@@ -5,6 +5,8 @@ from castor_extractor.uploader import FileType # type: ignore
|
|
|
5
5
|
from castor_extractor.uploader import upload # type: ignore
|
|
6
6
|
from castor_extractor.uploader import upload_manifest # type: ignore
|
|
7
7
|
|
|
8
|
+
FILE_TYPES = {FileType.QUALITY, FileType.VIZ, FileType.WAREHOUSE}
|
|
9
|
+
|
|
8
10
|
logging.basicConfig(level=logging.INFO, format="%(levelname)s - %(message)s")
|
|
9
11
|
|
|
10
12
|
|
|
@@ -51,7 +53,7 @@ def main():
|
|
|
51
53
|
params = _args()
|
|
52
54
|
|
|
53
55
|
file_type = params.get("file_type")
|
|
54
|
-
if file_type in
|
|
56
|
+
if file_type in FILE_TYPES:
|
|
55
57
|
upload(**params)
|
|
56
58
|
|
|
57
59
|
if file_type == FileType.DBT:
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import logging
|
|
1
2
|
from enum import Enum
|
|
2
3
|
from typing import Optional
|
|
3
4
|
|
|
@@ -5,9 +6,12 @@ import requests
|
|
|
5
6
|
|
|
6
7
|
from .credentials import CredentialsKey, DbtCredentials, get_value
|
|
7
8
|
|
|
9
|
+
logger = logging.getLogger(__name__)
|
|
10
|
+
|
|
8
11
|
_CLOUD_URL = "https://cloud.getdbt.com/api/v2/accounts"
|
|
9
12
|
_DATA_KEY = "data"
|
|
10
13
|
_MANIFEST_PATH = "manifest.json"
|
|
14
|
+
_SUCCESSFUL_RUN_STATUS = 10
|
|
11
15
|
|
|
12
16
|
|
|
13
17
|
class ContentType(Enum):
|
|
@@ -47,20 +51,32 @@ class DbtClient:
|
|
|
47
51
|
headers=headers,
|
|
48
52
|
params=params,
|
|
49
53
|
)
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
+
try:
|
|
55
|
+
result = response.json()
|
|
56
|
+
except:
|
|
57
|
+
context = f"{url}, status {response.status_code}"
|
|
58
|
+
raise ValueError(f"Couldn't extract data from {context}")
|
|
59
|
+
else:
|
|
60
|
+
if content_type == ContentType.JSON:
|
|
61
|
+
return result[_DATA_KEY]
|
|
62
|
+
return result
|
|
54
63
|
|
|
55
64
|
def _infer_account_id(self) -> int:
|
|
56
65
|
result = self._call(url=_CLOUD_URL)
|
|
57
66
|
return result[0]["id"]
|
|
58
67
|
|
|
59
68
|
def _last_run_id(self) -> int:
|
|
69
|
+
"""
|
|
70
|
+
Extract last successful run id
|
|
71
|
+
https://docs.getdbt.com/dbt-cloud/api-v2#tag/Runs/operation/listRunsForAccount
|
|
72
|
+
"""
|
|
73
|
+
|
|
60
74
|
url = f"{_CLOUD_URL}/{self._account_id}/runs/"
|
|
75
|
+
|
|
61
76
|
params = {
|
|
62
77
|
"job_definition_id": self._credentials.job_id,
|
|
63
78
|
"order_by": "-finished_at",
|
|
79
|
+
"status": _SUCCESSFUL_RUN_STATUS,
|
|
64
80
|
"limit": 1,
|
|
65
81
|
}
|
|
66
82
|
return self._call(url, params)[0]["id"]
|
|
@@ -72,6 +88,8 @@ class DbtClient:
|
|
|
72
88
|
"""
|
|
73
89
|
run_id = self._last_run_id()
|
|
74
90
|
url = f"{_CLOUD_URL}/{self._account_id}/runs/{run_id}/artifacts/{_MANIFEST_PATH}"
|
|
91
|
+
logger.info(f"Extracting manifest from run id {run_id} with url {url}")
|
|
92
|
+
|
|
75
93
|
# setting text content as a workaround to this issue
|
|
76
94
|
# https://stackoverflow.com/questions/68201659/dbt-cloud-api-to-extract-run-artifacts
|
|
77
95
|
return self._call(url, content_type=ContentType.TEXT)
|
|
@@ -7,12 +7,14 @@ class FileType(Enum):
|
|
|
7
7
|
"""type of file to load"""
|
|
8
8
|
|
|
9
9
|
DBT = "DBT"
|
|
10
|
+
QUALITY = "QUALITY"
|
|
10
11
|
VIZ = "VIZ"
|
|
11
12
|
WAREHOUSE = "WAREHOUSE"
|
|
12
13
|
|
|
13
14
|
|
|
14
15
|
PATH_TEMPLATES = {
|
|
15
16
|
FileType.DBT: "transformation-{source_id}/{timestamp}-manifest.json",
|
|
17
|
+
FileType.QUALITY: "quality-{source_id}/{timestamp}-{filename}",
|
|
16
18
|
FileType.VIZ: "visualization-{source_id}/{filename}",
|
|
17
19
|
FileType.WAREHOUSE: "warehouse-{source_id}/{filename}",
|
|
18
20
|
}
|
|
@@ -57,7 +57,6 @@ WHERE TRUE
|
|
|
57
57
|
'ROLLBACK',
|
|
58
58
|
'DESCRIBE',
|
|
59
59
|
'ALTER_SESSION',
|
|
60
|
-
'COPY', -- https://docs.snowflake.com/en/sql-reference/sql/copy-into-location.html#syntax
|
|
61
60
|
'PUT_FILES',
|
|
62
61
|
'CREATE', -- create objects: stage|function|schema|procedure|file|storage|pipe|notification integration
|
|
63
62
|
'SET',
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
CHANGELOG.md,sha256=
|
|
1
|
+
CHANGELOG.md,sha256=DIidPXNKp9icL0ZTvm7mnNSGno2190ncEFar6BoR0Is,4796
|
|
2
2
|
LICENCE,sha256=sL-IGa4hweyya1HgzMskrRdybbIa2cktzxb5qmUgDg8,8254
|
|
3
3
|
README.md,sha256=_H5aVcA57LLStpQaYm0yYndJRuw7BqQKt46D1xogRJo,3390
|
|
4
4
|
castor_extractor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -15,7 +15,7 @@ castor_extractor/commands/extract_redshift.py,sha256=bdLp7d7ImZoKCkWc3f3NXF1imIz
|
|
|
15
15
|
castor_extractor/commands/extract_snowflake.py,sha256=KxUbbuBsKYy8hJxv_98YktoS-gemDp4hbWjGzj9sR1c,1799
|
|
16
16
|
castor_extractor/commands/extract_tableau.py,sha256=ysEE0DHPJk79MKwFqo7mIZMBGSY4Ad-4vLr4OMxRB5k,1390
|
|
17
17
|
castor_extractor/commands/file_check.py,sha256=HmPiuXWlwVWCgQ5lZMoYpuRAH9UJgaW2eIkdT-tHy_c,2667
|
|
18
|
-
castor_extractor/commands/upload.py,sha256=
|
|
18
|
+
castor_extractor/commands/upload.py,sha256=xutRBSzg5nxoMA-fmj7m5Y_96P7xFs2b4MehKfqvzSo,1930
|
|
19
19
|
castor_extractor/file_checker/__init__.py,sha256=OSt6YLhUT42U_Cp3LCLHMVruwDkksL75Ij13X2UPnVk,119
|
|
20
20
|
castor_extractor/file_checker/column.py,sha256=fMchy5v-Sd-0xuYS0V9mob7wnljslzWLhQGqrKGybdk,3097
|
|
21
21
|
castor_extractor/file_checker/column_test.py,sha256=1j8PxvmvmJgpd-mk30iMYOme32ovPSIn4yCXywFoXrg,1935
|
|
@@ -32,10 +32,10 @@ castor_extractor/transformation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm
|
|
|
32
32
|
castor_extractor/transformation/dbt/__init__.py,sha256=fynkZOuDwD4AFcAYFdUBUbBPC5HoaQjVu-Z2BMcSnoI,91
|
|
33
33
|
castor_extractor/transformation/dbt/assets.py,sha256=TqjktG7NeK_FUNAoOQJTtgCGVh8Cm9cTnoozNhXErmM,94
|
|
34
34
|
castor_extractor/transformation/dbt/client/__init__.py,sha256=-9TvcGyeANOnoqceq3MnRrM2i6YzK906SZqeJqfLOpg,86
|
|
35
|
-
castor_extractor/transformation/dbt/client/client.py,sha256=
|
|
35
|
+
castor_extractor/transformation/dbt/client/client.py,sha256=8SdcB5edeRHUUSz7HuTq67B_6RLo9O8z5lIOjyOOrpg,2938
|
|
36
36
|
castor_extractor/transformation/dbt/client/credentials.py,sha256=67mWV2AML8vt--o9-2bvBzlcigj-5ZdocUcUxdc7J30,746
|
|
37
37
|
castor_extractor/uploader/__init__.py,sha256=SSRtwjg-dNoxME-RJy9G1flASiUKAC5bH1htq3CURQg,75
|
|
38
|
-
castor_extractor/uploader/constant.py,sha256=
|
|
38
|
+
castor_extractor/uploader/constant.py,sha256=hEJlWYx0dyBzgo59XUBKCYIKEODpIc2DyzwAZIiNO8g,718
|
|
39
39
|
castor_extractor/uploader/env.py,sha256=5HSniVSOYVg4u38O4k8TB_qaJq9s8yJ1hjedkq_gdVg,878
|
|
40
40
|
castor_extractor/uploader/env_test.py,sha256=ClCWWtwd2N-5ClIDUxVMeKkWfhhOTxpppsXUDmdjxSg,472
|
|
41
41
|
castor_extractor/uploader/upload.py,sha256=NTXF4BlVEsRCA6S-SunyNHkcXN9JaRpK1W65ZeMWAcw,3353
|
|
@@ -158,7 +158,7 @@ castor_extractor/visualization/tableau/client/safe_mode.py,sha256=12pVLUns4BdK6o
|
|
|
158
158
|
castor_extractor/visualization/tableau/constants.py,sha256=O2CqeviFz122BumNHoJ1N-e1lzyqIHF9OYnGQttg4hg,126
|
|
159
159
|
castor_extractor/visualization/tableau/errors.py,sha256=WWvmnp5pdxFJqanPKeDRADZc0URSPxkJqxDI6bwoifQ,91
|
|
160
160
|
castor_extractor/visualization/tableau/extract.py,sha256=75Z21qeOyinJqnbWFo74Mk4Q0ja0yorss9ZKPc1eQFg,2873
|
|
161
|
-
castor_extractor/visualization/tableau/gql_fields.py,sha256=
|
|
161
|
+
castor_extractor/visualization/tableau/gql_fields.py,sha256=m03qXuJzP-4UfUnAVmV8RKBSNoeNl2wVWz8n9tMyGmI,4728
|
|
162
162
|
castor_extractor/visualization/tableau/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
163
163
|
castor_extractor/visualization/tableau/tests/unit/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
164
164
|
castor_extractor/visualization/tableau/tests/unit/assets/graphql/metadata/metadata_1_get.json,sha256=4iMvJ_VakDa67xN2ROraAccaz_DDxX6Y5Y1XnTU5F5Y,446
|
|
@@ -242,7 +242,7 @@ castor_extractor/warehouse/snowflake/queries/column_lineage.sql,sha256=YKBiZ6zyS
|
|
|
242
242
|
castor_extractor/warehouse/snowflake/queries/database.sql,sha256=ifZXoKUXtsrGOxml6AcNhA4yybIyatH5va7bcp-lgCU,483
|
|
243
243
|
castor_extractor/warehouse/snowflake/queries/grant_to_role.sql,sha256=O7AJ1LzoXGDFmiVvQ8EMJ5x8FSAnaxRPdmRyAlEmkUM,272
|
|
244
244
|
castor_extractor/warehouse/snowflake/queries/grant_to_user.sql,sha256=7AalVajU5vRRpIiys1igSwmDXirbwpMTvJr2ihSz2NE,143
|
|
245
|
-
castor_extractor/warehouse/snowflake/queries/query.sql,sha256
|
|
245
|
+
castor_extractor/warehouse/snowflake/queries/query.sql,sha256=-OYcWUvdPBkpOfezkZaW7hrOdDz3JyoqjNdRm_88Rsk,1779
|
|
246
246
|
castor_extractor/warehouse/snowflake/queries/role.sql,sha256=D0VvGxLZMwug2SvefhAsNR9YIun0fZvcDWkz891xSYM,96
|
|
247
247
|
castor_extractor/warehouse/snowflake/queries/schema.sql,sha256=HCDEw0Nj_GPHBNH3Ik_5BF4rkD5yBfSyeN9UaiFGrI4,730
|
|
248
248
|
castor_extractor/warehouse/snowflake/queries/table.sql,sha256=sSfJ2sNsn-pTVDiHQVJnwzcfq_MVZvddwpVgKuwP_n4,1378
|
|
@@ -259,7 +259,7 @@ castor_extractor/warehouse/synapse/queries/schema.sql,sha256=aX9xNrBD_ydwl-znGSF
|
|
|
259
259
|
castor_extractor/warehouse/synapse/queries/table.sql,sha256=mCE8bR1Vb7j7SwZW2gafcXidQ2fo1HwxcybA8wP2Kfs,1049
|
|
260
260
|
castor_extractor/warehouse/synapse/queries/user.sql,sha256=sTb_SS7Zj3AXW1SggKPLNMCd0qoTpL7XI_BJRMaEpBg,67
|
|
261
261
|
castor_extractor/warehouse/synapse/queries/view_ddl.sql,sha256=3EVbp5_yTgdByHFIPLHmnoOnqqLE77SrjAwFDvu4e54,249
|
|
262
|
-
castor_extractor-0.3.
|
|
263
|
-
castor_extractor-0.3.
|
|
264
|
-
castor_extractor-0.3.
|
|
265
|
-
castor_extractor-0.3.
|
|
262
|
+
castor_extractor-0.3.5.dist-info/entry_points.txt,sha256=kwmxu6k71-dgEuW0G5zD7LUcOsBhPCjp0cGtukkH3OA,915
|
|
263
|
+
castor_extractor-0.3.5.dist-info/WHEEL,sha256=vxFmldFsRN_Hx10GDvsdv1wroKq8r5Lzvjp6GZ4OO8c,88
|
|
264
|
+
castor_extractor-0.3.5.dist-info/METADATA,sha256=UjUUD5Ule0Pd-WganeadVraVcdTqtlLnWSt5TsbN8PU,6365
|
|
265
|
+
castor_extractor-0.3.5.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|