castor-extractor 0.21.1__py3-none-any.whl → 0.21.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 CHANGED
@@ -1,6 +1,22 @@
1
1
 
2
2
  # Changelog
3
3
 
4
+ ## 0.21.5 - 2024-11-20
5
+
6
+ * PostgreSQL: Fix schema extraction when owner is a role without login privilege
7
+
8
+ ## 0.21.4 - 2024-11-20
9
+
10
+ * Uploader: Support environment variables as settings
11
+
12
+ ## 0.21.3 - 2024-11-07
13
+
14
+ * Tableau: Fix metrics definition url
15
+
16
+ ## 0.21.2 - 2024-11-06
17
+
18
+ * Adding fetch method for confluence client
19
+
4
20
  ## 0.21.1 - 2024-10-23
5
21
 
6
22
  * Warning message to deprecate python < 3.9
@@ -1,32 +1,28 @@
1
- import argparse
2
1
  import logging
2
+ from argparse import ArgumentParser
3
3
 
4
4
  from castor_extractor.uploader import ( # type: ignore
5
5
  FileType,
6
- upload,
7
- upload_manifest,
6
+ upload_any,
8
7
  )
9
-
10
- FILE_TYPES = {FileType.QUALITY, FileType.VIZ, FileType.WAREHOUSE}
8
+ from castor_extractor.utils import parse_filled_arguments # type: ignore
11
9
 
12
10
  logging.basicConfig(level=logging.INFO, format="%(levelname)s - %(message)s")
13
11
 
14
12
 
15
- def _args():
16
- parser = argparse.ArgumentParser()
13
+ def _args() -> ArgumentParser:
14
+ parser = ArgumentParser()
17
15
  parser.add_argument(
18
16
  "-k",
19
17
  "--token",
20
- required=True,
21
- help="""API token provided by Castor""",
18
+ help="API token provided by CastorDoc",
22
19
  )
23
20
  parser.add_argument(
24
21
  "-s",
25
22
  "--source_id",
26
- required=True,
27
- help="source id provided by castor",
23
+ help="source id provided by CastorDoc",
28
24
  )
29
- group = parser.add_mutually_exclusive_group(required=True)
25
+ group = parser.add_mutually_exclusive_group(required=False)
30
26
  group.add_argument("-f", "--file_path", help="path to file to upload")
31
27
  group.add_argument(
32
28
  "-d",
@@ -44,25 +40,9 @@ def _args():
44
40
  ),
45
41
  choices=supported_file_type,
46
42
  )
47
- parsed = parser.parse_args()
48
- return {
49
- "token": parsed.token,
50
- "source_id": parsed.source_id,
51
- "file_path": parsed.file_path,
52
- "directory_path": parsed.directory_path,
53
- "file_type": FileType(parsed.file_type),
54
- }
43
+ return parser
55
44
 
56
45
 
57
46
  def main():
58
- params = _args()
59
-
60
- file_type = params.get("file_type")
61
- if file_type in FILE_TYPES:
62
- upload(**params)
63
-
64
- if file_type == FileType.DBT:
65
- dir_path = params.pop("directory_path")
66
- assert not dir_path
67
- del params["file_type"]
68
- upload_manifest(**params)
47
+ parser = _args()
48
+ upload_any(**parse_filled_arguments(parser))
@@ -1,6 +1,6 @@
1
1
  from functools import partial
2
2
  from http import HTTPStatus
3
- from typing import Optional
3
+ from typing import Iterator, Optional
4
4
 
5
5
  from ....utils import (
6
6
  APIClient,
@@ -8,6 +8,9 @@ from ....utils import (
8
8
  RequestSafeMode,
9
9
  fetch_all_pages,
10
10
  )
11
+ from ..assets import (
12
+ ConfluenceAsset,
13
+ )
11
14
  from .credentials import ConfluenceCredentials
12
15
  from .endpoints import ConfluenceEndpointFactory
13
16
  from .pagination import ConfluencePagination
@@ -58,3 +61,14 @@ class ConfluenceClient(APIClient):
58
61
  data=request_body,
59
62
  )
60
63
  yield from fetch_all_pages(request, ConfluencePagination)
64
+
65
+ def fetch(self, asset: ConfluenceAsset) -> Iterator[dict]:
66
+ """Returns the needed metadata for the queried asset"""
67
+ if asset == ConfluenceAsset.PAGES:
68
+ yield from self.pages()
69
+
70
+ elif asset == ConfluenceAsset.USERS:
71
+ yield from self.users()
72
+
73
+ else:
74
+ raise ValueError(f"This asset {asset} is unknown")
@@ -1,2 +1,2 @@
1
1
  from .constant import FileType
2
- from .upload import upload, upload_manifest
2
+ from .upload import upload, upload_any, upload_manifest
@@ -0,0 +1,24 @@
1
+ from typing import Optional
2
+
3
+ from pydantic import UUID4, Field
4
+ from pydantic_settings import BaseSettings, SettingsConfigDict
5
+
6
+ from .constant import FileType
7
+
8
+ UPLOADER_ENV_PREFIX = "CASTOR_UPLOADER_"
9
+
10
+
11
+ class UploaderSettings(BaseSettings):
12
+ """Class holding Castor uploader attributes"""
13
+
14
+ model_config = SettingsConfigDict(
15
+ env_prefix=UPLOADER_ENV_PREFIX,
16
+ extra="ignore",
17
+ populate_by_name=True,
18
+ )
19
+
20
+ directory_path: Optional[str] = None
21
+ file_path: Optional[str] = None
22
+ file_type: FileType
23
+ source_id: UUID4
24
+ token: str = Field(repr=False)
@@ -17,6 +17,7 @@ from .constant import (
17
17
  FileType,
18
18
  )
19
19
  from .env import get_blob_env
20
+ from .settings import UploaderSettings
20
21
  from .utils import iter_files
21
22
 
22
23
  logger = logging.getLogger(__name__)
@@ -95,13 +96,15 @@ def _upload(
95
96
  def upload_manifest(
96
97
  token: str,
97
98
  source_id: UUID,
98
- file_path: str,
99
+ file_path: Optional[str] = None,
99
100
  ) -> None:
100
101
  """
101
- credentials: path to file or dict
102
+ token: backend public API token
102
103
  source_id: id for the source
103
104
  file_path: path to the local manifest to upload
104
105
  """
106
+ if not file_path:
107
+ raise ValueError("file path is needed to upload a manifest")
105
108
  _upload(token, source_id, file_path, FileType.DBT)
106
109
 
107
110
 
@@ -113,7 +116,7 @@ def upload(
113
116
  directory_path: Optional[str] = None,
114
117
  ) -> None:
115
118
  """
116
- credentials: path to file or dict
119
+ token: backend public API token
117
120
  source_id: id for the source
118
121
  file_type: type of file(s) uploaded - see FileType Enum
119
122
  file_path: path to the local visualization or warehouse file to upload
@@ -130,3 +133,35 @@ def upload(
130
133
 
131
134
  for file_ in files:
132
135
  _upload(token, source_id, file_, file_type)
136
+
137
+
138
+ def upload_any(**kwargs) -> None:
139
+ """
140
+ entrypath to upload either a file or a manifest
141
+
142
+ token: backend public API token
143
+ source_id: id for the source
144
+ file_type: type of file(s) uploaded - see FileType Enum
145
+ file_path: path to the local visualization or warehouse file to upload
146
+ directory_path: path to the local directory containing files to upload
147
+ """
148
+
149
+ settings = UploaderSettings(**kwargs)
150
+ file_type = settings.file_type
151
+
152
+ if file_type == FileType.DBT:
153
+ assert not settings.directory_path
154
+ upload_manifest(
155
+ token=settings.token,
156
+ source_id=settings.source_id,
157
+ file_path=settings.file_path,
158
+ )
159
+ return None
160
+
161
+ upload(
162
+ token=settings.token,
163
+ source_id=settings.source_id,
164
+ file_type=file_type,
165
+ file_path=settings.file_path,
166
+ directory_path=settings.directory_path,
167
+ )
@@ -12,7 +12,7 @@ logger = logging.getLogger(__name__)
12
12
 
13
13
  _PULSE_API = "api/-/pulse"
14
14
 
15
- _METRICS_URL = "{base}/pulse/site/{site}/metrics/{definition_id}"
15
+ _METRICS_DEFINITION_URL = "{base}/pulse/site/{site}/{definition_id}"
16
16
 
17
17
 
18
18
  def _pick(
@@ -89,7 +89,7 @@ class TableauClientRestApi:
89
89
  site = self._get_site_name()
90
90
  base_url = self._server.server_address.strip("/")
91
91
  for row in data:
92
- row["metadata"]["url"] = _METRICS_URL.format(
92
+ row["metadata"]["url"] = _METRICS_DEFINITION_URL.format(
93
93
  base=base_url,
94
94
  site=site,
95
95
  definition_id=row["metadata"]["id"],
@@ -3,12 +3,12 @@ SELECT
3
3
  db.datname AS database_name,
4
4
  ns.oid::TEXT AS schema_id,
5
5
  ns.nspname AS schema_name,
6
- u.usename AS schema_owner,
7
- u.usesysid AS schema_owner_id,
6
+ r.rolname AS schema_owner,
7
+ ns.nspowner AS schema_owner_id,
8
8
  de.description AS "comment"
9
9
  FROM pg_catalog.pg_namespace AS ns
10
10
  CROSS JOIN pg_catalog.pg_database AS db
11
- JOIN pg_catalog.pg_user AS u ON u.usesysid = ns.nspowner
11
+ LEFT JOIN pg_catalog.pg_roles AS r ON r.oid = ns.nspowner
12
12
  LEFT JOIN pg_catalog.pg_description AS de ON de.classoid = ns.oid
13
13
  WHERE TRUE
14
14
  AND db.datname = CURRENT_DATABASE()
@@ -4,14 +4,14 @@ WITH ids AS (
4
4
  t.relname AS table_name,
5
5
  n.nspname AS schema_name,
6
6
  n.oid AS schema_id,
7
- u.usename AS table_owner,
7
+ r.rolname AS table_owner,
8
8
  t.relowner AS table_owner_id,
9
9
  td.description AS "comment",
10
10
  t.reltuples::BIGINT AS tuples
11
11
  FROM pg_class AS t
12
12
  JOIN pg_catalog.pg_namespace AS n ON n.oid = t.relnamespace
13
13
  LEFT JOIN pg_catalog.pg_description AS td ON td.objoid = t.oid AND td.objsubid = 0
14
- LEFT JOIN pg_catalog.pg_user AS u ON u.usesysid = t.relowner
14
+ LEFT JOIN pg_catalog.pg_roles AS r ON r.oid = t.relowner
15
15
  WHERE TRUE
16
16
  AND n.nspname NOT LIKE 'pg_%%'
17
17
  AND n.nspname NOT IN ('catalog_history', 'information_schema')
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: castor-extractor
3
- Version: 0.21.1
3
+ Version: 0.21.5
4
4
  Summary: Extract your metadata assets.
5
5
  Home-page: https://www.castordoc.com/
6
6
  License: EULA
@@ -208,6 +208,22 @@ For any questions or bug report, contact us at [support@castordoc.com](mailto:su
208
208
 
209
209
  # Changelog
210
210
 
211
+ ## 0.21.5 - 2024-11-20
212
+
213
+ * PostgreSQL: Fix schema extraction when owner is a role without login privilege
214
+
215
+ ## 0.21.4 - 2024-11-20
216
+
217
+ * Uploader: Support environment variables as settings
218
+
219
+ ## 0.21.3 - 2024-11-07
220
+
221
+ * Tableau: Fix metrics definition url
222
+
223
+ ## 0.21.2 - 2024-11-06
224
+
225
+ * Adding fetch method for confluence client
226
+
211
227
  ## 0.21.1 - 2024-10-23
212
228
 
213
229
  * Warning message to deprecate python < 3.9
@@ -1,4 +1,4 @@
1
- CHANGELOG.md,sha256=U0folo6uva597R9IArkQzRau3UldJIdvq99aWOEWKkA,14355
1
+ CHANGELOG.md,sha256=HxssLs5JkyCp21TZ3l85OSMkFvaO5mrr3pZRXM-EqUg,14672
2
2
  Dockerfile,sha256=xQ05-CFfGShT3oUqaiumaldwA288dj9Yb_pxofQpufg,301
3
3
  DockerfileUsage.md,sha256=2hkJQF-5JuuzfPZ7IOxgM6QgIQW7l-9oRMFVwyXC4gE,998
4
4
  LICENCE,sha256=sL-IGa4hweyya1HgzMskrRdybbIa2cktzxb5qmUgDg8,8254
@@ -27,7 +27,7 @@ castor_extractor/commands/extract_sqlserver.py,sha256=lwhbcNChaXHZgMgSOch3faVr7W
27
27
  castor_extractor/commands/extract_tableau.py,sha256=VUb_1Y85EzfF1f9OaCQQt8kFYBdp0u31Mw1Wm2fkxWs,1221
28
28
  castor_extractor/commands/extract_thoughtspot.py,sha256=caAYJlH-vK7u5IUB6OKXxcaWfLgc7d_XqnFDWK6YNS4,639
29
29
  castor_extractor/commands/file_check.py,sha256=VSD84kpQKf7b0wJOhUgkJQ9n4mK3v52sjMWL7wkNYa0,2667
30
- castor_extractor/commands/upload.py,sha256=WLDI3zDmK2CjtbxiMWX2mZGjxx8DozfCw6tLE3CAMcE,1833
30
+ castor_extractor/commands/upload.py,sha256=rLXp7gQ8zb1kLbho4FT87q8eJd8Gvo_TkyIynAaQ-4s,1342
31
31
  castor_extractor/file_checker/__init__.py,sha256=OSt6YLhUT42U_Cp3LCLHMVruwDkksL75Ij13X2UPnVk,119
32
32
  castor_extractor/file_checker/column.py,sha256=fMchy5v-Sd-0xuYS0V9mob7wnljslzWLhQGqrKGybdk,3097
33
33
  castor_extractor/file_checker/column_test.py,sha256=1j8PxvmvmJgpd-mk30iMYOme32ovPSIn4yCXywFoXrg,1935
@@ -43,7 +43,7 @@ castor_extractor/knowledge/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJ
43
43
  castor_extractor/knowledge/confluence/__init__.py,sha256=pRT615pMDlB7Ifs09erVn2EdpZHgkvX5selemWU3VPE,129
44
44
  castor_extractor/knowledge/confluence/assets.py,sha256=zv2G2LB8H0fKDbVJ4kHrAjbqehXI_K-wgd_ghSXGFvs,144
45
45
  castor_extractor/knowledge/confluence/client/__init__.py,sha256=ALAzo0JEhxFzH2FnIO6HmtkAGS2_bGY8KXXMcTGV3aE,84
46
- castor_extractor/knowledge/confluence/client/client.py,sha256=ZgAUlEGwpSN1QZAFGpU-7gob_wWI3wpBh1iTycxUZc4,1667
46
+ castor_extractor/knowledge/confluence/client/client.py,sha256=ZBabhxlaatbfT19ijGTmF0UJdWSANz7_q5IU7AmB4PM,2090
47
47
  castor_extractor/knowledge/confluence/client/credentials.py,sha256=2LUjnCOMwq2NBrkHty99TpWlgyOOsYjwC9NeekZMH84,422
48
48
  castor_extractor/knowledge/confluence/client/endpoints.py,sha256=b7PIvw9_W942L4zsEZa__KhZDTo4yt-CdIO0eas69TE,736
49
49
  castor_extractor/knowledge/confluence/client/pagination.py,sha256=ty4meiMEujDVSiQyOJTibd-ReYyDyGezdFuk7EAGtMA,862
@@ -68,11 +68,12 @@ castor_extractor/quality/soda/client/credentials.py,sha256=R1g7nHpJlQ5hBjtUFN06Q
68
68
  castor_extractor/quality/soda/client/endpoints.py,sha256=x3B-XlnDF8NJMuk-81N72_6HA-YZEzA895khLyj0j54,228
69
69
  castor_extractor/quality/soda/client/pagination.py,sha256=IrAnju5CFipHarTLZRWZflVZ3KHoRVMvaCaNAePHVug,555
70
70
  castor_extractor/types.py,sha256=Hd_shbsGAknJLTrAk3SBxZeFPOlbWBXXjIscC9C7CW8,1281
71
- castor_extractor/uploader/__init__.py,sha256=SSRtwjg-dNoxME-RJy9G1flASiUKAC5bH1htq3CURQg,75
71
+ castor_extractor/uploader/__init__.py,sha256=A4bq_SrEtKAsl0r_D_duSTvL5WIQjVfsMy7tDx9IKg0,87
72
72
  castor_extractor/uploader/constant.py,sha256=yTigLHDlYwoRr6CpFIl7ReElFsQd4H-qkluMZJPWSx0,865
73
73
  castor_extractor/uploader/env.py,sha256=5HSniVSOYVg4u38O4k8TB_qaJq9s8yJ1hjedkq_gdVg,878
74
74
  castor_extractor/uploader/env_test.py,sha256=ClCWWtwd2N-5ClIDUxVMeKkWfhhOTxpppsXUDmdjxSg,472
75
- castor_extractor/uploader/upload.py,sha256=c86NP4ZxWnz3Hy1iWDYd9qjJSSjZ1bLq3fxVGBIU4Rc,3238
75
+ castor_extractor/uploader/settings.py,sha256=3MvOX-UFRqrLZoiT7wYn9jUGro7NX4RCafYzrXrLQtA,590
76
+ castor_extractor/uploader/upload.py,sha256=XGoqr4UdpsARyLG0Mp5enBqDvc6m_WCK9nMB3yhUwlM,4296
76
77
  castor_extractor/uploader/upload_test.py,sha256=7fwstdQe7FjuwGilsCdFpEQr1qLoR2WTRUzyy93fISw,402
77
78
  castor_extractor/uploader/utils.py,sha256=Tx_i875L2vJ8btOLV3-L0UMEFiyhH8E5n0XXRyLjO0Y,793
78
79
  castor_extractor/utils/__init__.py,sha256=jyYquzC2-R-UYl3VTP49ZDHB0IErGogTPMy3GfScbaA,1524
@@ -285,7 +286,7 @@ castor_extractor/visualization/tableau_revamp/assets.py,sha256=8sJsK6Qixao6xVmVa
285
286
  castor_extractor/visualization/tableau_revamp/client/__init__.py,sha256=wmS9uLtUiqNYVloi0-DgD8d2qzu3RVZEAtWiaDp6G_M,90
286
287
  castor_extractor/visualization/tableau_revamp/client/client.py,sha256=oaxvPsCccAcTWooXmDQNcJ6RFUVsCUzl6HxaHIwh5kU,7564
287
288
  castor_extractor/visualization/tableau_revamp/client/client_metadata_api.py,sha256=yNnGR3Tk32TUmaDejaz5fkw2p9DtmMeCv5rsZNOHUfY,3047
288
- castor_extractor/visualization/tableau_revamp/client/client_rest_api.py,sha256=0g8AddrhzirRCUWR2jrudPR02mk4Of5YilWth7zJO-g,4016
289
+ castor_extractor/visualization/tableau_revamp/client/client_rest_api.py,sha256=HZ6KdNJ6sqhWElfpYlUwbZDJXxoKkNc3p-YAKExzDxM,4030
289
290
  castor_extractor/visualization/tableau_revamp/client/client_tsc.py,sha256=BBwIOqK2zU66udFRmLGmB_3J1ILGhVOY5Hq4nmsonF0,1853
290
291
  castor_extractor/visualization/tableau_revamp/client/credentials.py,sha256=qA-EaX-4rbQRsn8v4zWh5Kh784ndHLjJaoZwnkQgCyo,1905
291
292
  castor_extractor/visualization/tableau_revamp/client/errors.py,sha256=dTe1shqmWmAXpDpCz-E24m8dGYjt6rvIGV9qQb4jnvI,150
@@ -364,8 +365,8 @@ castor_extractor/warehouse/postgres/queries/.sqlfluff,sha256=Z7nq1jdnKxpOKpKTpJI
364
365
  castor_extractor/warehouse/postgres/queries/column.sql,sha256=N7UzWK0aslvoaXQritSf-EE7h8fpadT4AYFaCwfMo9s,1632
365
366
  castor_extractor/warehouse/postgres/queries/database.sql,sha256=GRM-CHI3EGCjpEEvgzdefLhV74EPTqCOCaud0S1Rv_E,241
366
367
  castor_extractor/warehouse/postgres/queries/group.sql,sha256=8p0wlqllnwOTiAgiV237DvFYHGOEcYwaHdyqVQg3F6E,101
367
- castor_extractor/warehouse/postgres/queries/schema.sql,sha256=cd_bx8uasswxtEPNOuHeN49YBcbeKDvl4yULbpXkEfE,592
368
- castor_extractor/warehouse/postgres/queries/table.sql,sha256=ok9IGlX8b2v8AETpgG9ns-wfOlnyxz73enEd6tVOLGw,1489
368
+ castor_extractor/warehouse/postgres/queries/schema.sql,sha256=brzNqvkoARjOgXUSu1nvCIXueS6QRk3ozQr_OoRwJdY,594
369
+ castor_extractor/warehouse/postgres/queries/table.sql,sha256=eHiajIJnBj43wpx19fYpGbbI_zvp3-IhqwUv9aVohLo,1485
369
370
  castor_extractor/warehouse/postgres/queries/user.sql,sha256=sEXveJAuNvZacvpI6WfwsX6VavoMb2VqYA32f6Dt-_Y,170
370
371
  castor_extractor/warehouse/postgres/query.py,sha256=5QmI79BP_EjqxeABNg56rxuM9XuuXHuFFzCk6svnFEw,540
371
372
  castor_extractor/warehouse/redshift/__init__.py,sha256=CC82SejYDlwYhZhhn40ln-oTsRx7AJ1Km61cxPkymjE,125
@@ -424,8 +425,8 @@ castor_extractor/warehouse/sqlserver/queries/table.sql,sha256=kbBQP-TdG5px1IVgyx
424
425
  castor_extractor/warehouse/sqlserver/queries/user.sql,sha256=gOrZsMVypusR2dc4vwVs4E1a-CliRsr_UjnD2EbXs-A,94
425
426
  castor_extractor/warehouse/sqlserver/query.py,sha256=j_d5-HMnzBouwGfywVZMRSSwbXzPvzDWlFCZmvxcoGQ,539
426
427
  castor_extractor/warehouse/synapse/queries/column.sql,sha256=lNcFoIW3Y0PFOqoOzJEXmPvZvfAsY0AP63Mu2LuPzPo,1351
427
- castor_extractor-0.21.1.dist-info/LICENCE,sha256=sL-IGa4hweyya1HgzMskrRdybbIa2cktzxb5qmUgDg8,8254
428
- castor_extractor-0.21.1.dist-info/METADATA,sha256=28gV2BAN9hz_TdzFHMxezHikWiOLwTczn0BwVKGrCy0,21575
429
- castor_extractor-0.21.1.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
430
- castor_extractor-0.21.1.dist-info/entry_points.txt,sha256=7aVSxc-_2dicp28Ow-S4y0p4wGoTm9zGmVptMvfLdw8,1649
431
- castor_extractor-0.21.1.dist-info/RECORD,,
428
+ castor_extractor-0.21.5.dist-info/LICENCE,sha256=sL-IGa4hweyya1HgzMskrRdybbIa2cktzxb5qmUgDg8,8254
429
+ castor_extractor-0.21.5.dist-info/METADATA,sha256=-LHZIKLW0VI1evr0xohzYnR1CBZomKpv_a_khkkShcA,21892
430
+ castor_extractor-0.21.5.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
431
+ castor_extractor-0.21.5.dist-info/entry_points.txt,sha256=7aVSxc-_2dicp28Ow-S4y0p4wGoTm9zGmVptMvfLdw8,1649
432
+ castor_extractor-0.21.5.dist-info/RECORD,,