castor-extractor 0.24.20__py3-none-any.whl → 0.24.21__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,5 +1,9 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.24.21 - 2025-05-26
4
+
5
+ * Looker Studio: add option to skip the extraction of view activity logs
6
+
3
7
  ## 0.24.20 - 2025-05-19
4
8
 
5
9
  * Powerbi: allow custom api base and login url
@@ -24,6 +24,12 @@ def main():
24
24
  "This can be the same file path as for Looker Studio."
25
25
  ),
26
26
  )
27
+ parser.add_argument(
28
+ "--skip-view-activity-logs",
29
+ action="store_true",
30
+ default=False,
31
+ help="Skips the extraction of activity logs",
32
+ )
27
33
 
28
34
  parser.add_argument("-o", "--output", help="Directory to write to")
29
35
 
@@ -1,7 +1,11 @@
1
- from ...types import ExternalAsset
1
+ from ...types import ExternalAsset, classproperty
2
2
 
3
3
 
4
4
  class LookerStudioAsset(ExternalAsset):
5
5
  ASSETS = "assets"
6
6
  SOURCE_QUERIES = "source_queries"
7
7
  VIEW_ACTIVITY = "view_activity"
8
+
9
+ @classproperty
10
+ def optional(cls) -> set["LookerStudioAsset"]:
11
+ return {LookerStudioAsset.VIEW_ACTIVITY}
@@ -12,7 +12,6 @@ from ....utils import (
12
12
  )
13
13
  from .credentials import LookerStudioCredentials
14
14
  from .pagination import LookerStudioPagination
15
- from .scopes import SCOPES
16
15
 
17
16
  USER_EMAIL_FIELD = "primaryEmail"
18
17
 
@@ -26,7 +25,7 @@ class AdminSDKClient:
26
25
  def __init__(self, credentials: LookerStudioCredentials):
27
26
  self._credentials = Credentials.from_service_account_info(
28
27
  credentials.model_dump(),
29
- scopes=SCOPES,
28
+ scopes=credentials.scopes,
30
29
  subject=credentials.admin_email, # impersonates an admin
31
30
  )
32
31
  self.directory_api = discovery.build(
@@ -1,5 +1,18 @@
1
+ from typing import Optional
2
+
1
3
  from pydantic import BaseModel, SecretStr, field_serializer
2
4
 
5
+ SCOPES_NO_ACTIVITY: tuple[str, ...] = (
6
+ "https://www.googleapis.com/auth/datastudio",
7
+ "https://www.googleapis.com/auth/userinfo.profile",
8
+ "https://www.googleapis.com/auth/admin.directory.user.readonly",
9
+ )
10
+
11
+ DEFAULT_SCOPES: tuple[str, ...] = (
12
+ *SCOPES_NO_ACTIVITY,
13
+ "https://www.googleapis.com/auth/admin.reports.audit.readonly",
14
+ )
15
+
3
16
 
4
17
  class LookerStudioCredentials(BaseModel):
5
18
  """
@@ -19,6 +32,14 @@ class LookerStudioCredentials(BaseModel):
19
32
  token_uri: str
20
33
  type: str
21
34
 
35
+ has_view_activity_logs: Optional[bool] = True
36
+ scopes: Optional[tuple] = DEFAULT_SCOPES
37
+
38
+ def model_post_init(self, __context):
39
+ """Set scopes based on has_view_activity_logs after initialization"""
40
+ if self.has_view_activity_logs is False:
41
+ self.scopes = SCOPES_NO_ACTIVITY
42
+
22
43
  @field_serializer("private_key")
23
44
  def dump_secret(self, pk):
24
45
  """When using model_dump, show private_key value"""
@@ -16,7 +16,6 @@ from .credentials import LookerStudioCredentials
16
16
  from .endpoints import LookerStudioAPIEndpoint
17
17
  from .enums import LookerStudioAssetType
18
18
  from .pagination import LookerStudioPagination
19
- from .scopes import SCOPES
20
19
 
21
20
 
22
21
  @contextmanager
@@ -47,7 +46,8 @@ class LookerStudioAPIAuth(BearerAuth):
47
46
  that user and make requests on that user's behalf.
48
47
  """
49
48
  self._credentials = Credentials.from_service_account_info(
50
- credentials.model_dump(), scopes=SCOPES
49
+ credentials.model_dump(),
50
+ scopes=credentials.scopes,
51
51
  )
52
52
  if subject:
53
53
  self._credentials = self._credentials.with_subject(subject)
@@ -23,8 +23,14 @@ LOOKER_STUDIO_ADMIN_EMAIL = "CASTOR_LOOKER_STUDIO_ADMIN_EMAIL"
23
23
 
24
24
  def iterate_all_data(
25
25
  client: LookerStudioClient,
26
+ has_view_activity_logs: bool = True,
26
27
  ) -> Iterable[tuple[LookerStudioAsset, Union[list, dict]]]:
27
- for asset in LookerStudioAsset:
28
+ assets_to_extract = LookerStudioAsset.mandatory
29
+
30
+ if has_view_activity_logs:
31
+ assets_to_extract.add(LookerStudioAsset.VIEW_ACTIVITY)
32
+
33
+ for asset in assets_to_extract:
28
34
  logger.info(f"Extracting {asset.name} from API")
29
35
  data = list(deep_serialize(client.fetch(asset)))
30
36
  yield asset, data
@@ -45,6 +51,8 @@ def _credentials(params: dict) -> LookerStudioCredentials:
45
51
  LOOKER_STUDIO_ADMIN_EMAIL
46
52
  )
47
53
  credentials["admin_email"] = admin_email
54
+ has_view_activity_logs = not params["skip_view_activity_logs"]
55
+ credentials["has_view_activity_logs"] = has_view_activity_logs
48
56
  return LookerStudioCredentials(**credentials)
49
57
 
50
58
 
@@ -68,7 +76,10 @@ def extract_all(**kwargs) -> None:
68
76
  the given output_directory.
69
77
  """
70
78
  output_directory = kwargs.get("output") or from_env(OUTPUT_DIR)
79
+
71
80
  credentials = _credentials(kwargs)
81
+ has_view_activity_logs = bool(credentials.has_view_activity_logs)
82
+
72
83
  bigquery_credentials = _bigquery_credentials_or_none(kwargs)
73
84
 
74
85
  client = LookerStudioClient(
@@ -77,7 +88,7 @@ def extract_all(**kwargs) -> None:
77
88
  )
78
89
  ts = current_timestamp()
79
90
 
80
- for key, data in iterate_all_data(client):
91
+ for key, data in iterate_all_data(client, has_view_activity_logs):
81
92
  filename = get_output_filename(key.name.lower(), output_directory, ts)
82
93
  write_json(filename, data)
83
94
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: castor-extractor
3
- Version: 0.24.20
3
+ Version: 0.24.21
4
4
  Summary: Extract your metadata assets.
5
5
  Home-page: https://www.castordoc.com/
6
6
  License: EULA
@@ -215,6 +215,10 @@ For any questions or bug report, contact us at [support@coalesce.io](mailto:supp
215
215
 
216
216
  # Changelog
217
217
 
218
+ ## 0.24.21 - 2025-05-26
219
+
220
+ * Looker Studio: add option to skip the extraction of view activity logs
221
+
218
222
  ## 0.24.20 - 2025-05-19
219
223
 
220
224
  * Powerbi: allow custom api base and login url
@@ -1,4 +1,4 @@
1
- CHANGELOG.md,sha256=NxSwszCNlJ8oD2ffivq3g75DK436mue9WwilR0r6bE4,17760
1
+ CHANGELOG.md,sha256=tja1IyeA0_DdgOOJLdH8WMTmSRucj5bnvR0G0tg_Nsk,17859
2
2
  Dockerfile,sha256=xQ05-CFfGShT3oUqaiumaldwA288dj9Yb_pxofQpufg,301
3
3
  DockerfileUsage.md,sha256=2hkJQF-5JuuzfPZ7IOxgM6QgIQW7l-9oRMFVwyXC4gE,998
4
4
  LICENCE,sha256=sL-IGa4hweyya1HgzMskrRdybbIa2cktzxb5qmUgDg8,8254
@@ -10,7 +10,7 @@ castor_extractor/commands/extract_confluence.py,sha256=blYcnDqywXNKRQ1aZAD9FclhL
10
10
  castor_extractor/commands/extract_databricks.py,sha256=SVKyoa-BBUQAM6HRHf1Wdg9-tpICic2yyvXQwHcNBhA,1264
11
11
  castor_extractor/commands/extract_domo.py,sha256=jvAawUsUTHrwCn_koK6StmQr4n_b5GyvJi6uu6WS0SM,1061
12
12
  castor_extractor/commands/extract_looker.py,sha256=cySLiolLCgrREJ9d0kMrJ7P8K3efHTBTzShalWVfI3A,1214
13
- castor_extractor/commands/extract_looker_studio.py,sha256=e79gbyTtCexRz5pg_Pp55GWkXJZWjm6NvVclmvcR0lM,916
13
+ castor_extractor/commands/extract_looker_studio.py,sha256=M7wx8XZScLizCI2vq80aj88vYrdiHChiCiebrrChlZY,1090
14
14
  castor_extractor/commands/extract_metabase_api.py,sha256=NXctea4GT_1iRDitY92nV3TKSqhjEUwYSxwPJMRS3iw,786
15
15
  castor_extractor/commands/extract_metabase_db.py,sha256=tYIhTPPgj1mN-07LyWcL6e-YoGp7HCWda58-5Ukyg_I,1255
16
16
  castor_extractor/commands/extract_mode.py,sha256=Q4iO-VAKMg4zFPejhAO-foZibL5Ht3jsnhWKwJ0oqUU,823
@@ -186,18 +186,17 @@ castor_extractor/visualization/looker/fields.py,sha256=7oC7p-3Wp7XHBP_FT_D1wH3kI
186
186
  castor_extractor/visualization/looker/fields_test.py,sha256=7Cwq8Qky6aTZg8nCHp1gmPJtd9pGNB4QeMIRRWdHo5w,782
187
187
  castor_extractor/visualization/looker/multithreading.py,sha256=Muuh3usBLqtv3sfHoyPYJ6jJ7V5ajR6N9ZJ_F-bNc60,2608
188
188
  castor_extractor/visualization/looker_studio/__init__.py,sha256=GccG-GJXoNhjXFPkw-rHHZ0SXVQTFKjqkMIYHVeu3T4,175
189
- castor_extractor/visualization/looker_studio/assets.py,sha256=lFIqr8EB6eK-Mf80R_x2qAscCyX7ZUcOcHVef1CM9B0,173
189
+ castor_extractor/visualization/looker_studio/assets.py,sha256=rI73rbVrfwkkepqZr0zPouP2lPUfJxSi21RKtOTHtAA,308
190
190
  castor_extractor/visualization/looker_studio/client/__init__.py,sha256=YkQaVDJa-7KSwdOLjtgKJMRiafbGNKC_46YVx0hYZ1Q,129
191
- castor_extractor/visualization/looker_studio/client/admin_sdk_client.py,sha256=hYKdU6TlWKkXx07r6HsZ4Wbxhasx8DP_jO6iDCjHjgk,3508
191
+ castor_extractor/visualization/looker_studio/client/admin_sdk_client.py,sha256=HIeyT9JTW1TPwVzD2Q-VfJ99jMP80Z-4CznKAnTnp2w,3493
192
192
  castor_extractor/visualization/looker_studio/client/client.py,sha256=6sTfLRUhuxhkqDjC2ZBEaw6YnR6ze8-_VW2rc1u9Ksk,3191
193
- castor_extractor/visualization/looker_studio/client/credentials.py,sha256=QImJPh8VctkrGt65UiU5hM12JI4WdCMSUFt88aiOoLw,657
193
+ castor_extractor/visualization/looker_studio/client/credentials.py,sha256=F4ISI8Ua_HJsMuGhYql28o3hKYR4sL_uzkrUkRiekRo,1347
194
194
  castor_extractor/visualization/looker_studio/client/endpoints.py,sha256=5eY-ffqNDdlDBOOpiF7LpjyHMrzeClJktidCr1pTDUs,669
195
195
  castor_extractor/visualization/looker_studio/client/enums.py,sha256=fHgemTaQpnwee8cw1YQVDsVnH--vTyFwT4Px8aVYYHQ,167
196
- castor_extractor/visualization/looker_studio/client/looker_studio_api_client.py,sha256=oySC6rsppj67RSifxwSCw4bFrz1Irx6IFJhX7tc_v1E,4087
196
+ castor_extractor/visualization/looker_studio/client/looker_studio_api_client.py,sha256=Phq378VEaFLD-nyP2_A1wge6HUP45jSthhlNjD7aqSg,4085
197
197
  castor_extractor/visualization/looker_studio/client/pagination.py,sha256=9HQ3Rkdiz2VB6AvYtZ0F-WouiD0pMmdZyAmkv-3wh08,783
198
198
  castor_extractor/visualization/looker_studio/client/queries/query.sql,sha256=Ub4rdrJ5WTPWKI-eVmXrNMv0Ktmti4b-93zZBr0xEB0,1426
199
- castor_extractor/visualization/looker_studio/client/scopes.py,sha256=824cqqgZuGq4L-rPNoHJe0ibXsxkRwB0CLG_kqw9Q0g,256
200
- castor_extractor/visualization/looker_studio/extract.py,sha256=cHyroNZ1fKoBTvIbEebnKDrU3xpkcEgIPJy75ljCL70,2607
199
+ castor_extractor/visualization/looker_studio/extract.py,sha256=uNpvg4wtFflmpkqXFfo_9Nm12AEKXBOCKKajIggySho,3026
201
200
  castor_extractor/visualization/metabase/__init__.py,sha256=3E36cmkMyEgBB6Ot5rWk-N75i0G-7k24QTlc-Iol4pM,193
202
201
  castor_extractor/visualization/metabase/assets.py,sha256=nu3FwQBU_hdS2DBvgXAwQlEEi76QiNK2tMKEtMyctaY,2874
203
202
  castor_extractor/visualization/metabase/client/__init__.py,sha256=KBvaPMofBRV3m_sZAnKNCrJGr-Z88EbpdzEzWPQ_uBk,99
@@ -426,8 +425,8 @@ castor_extractor/warehouse/sqlserver/queries/table.sql,sha256=kbBQP-TdG5px1IVgyx
426
425
  castor_extractor/warehouse/sqlserver/queries/user.sql,sha256=gOrZsMVypusR2dc4vwVs4E1a-CliRsr_UjnD2EbXs-A,94
427
426
  castor_extractor/warehouse/sqlserver/query.py,sha256=g0hPT-RmeGi2DyenAi3o72cTlQsLToXIFYojqc8E5fQ,533
428
427
  castor_extractor/warehouse/synapse/queries/column.sql,sha256=lNcFoIW3Y0PFOqoOzJEXmPvZvfAsY0AP63Mu2LuPzPo,1351
429
- castor_extractor-0.24.20.dist-info/LICENCE,sha256=sL-IGa4hweyya1HgzMskrRdybbIa2cktzxb5qmUgDg8,8254
430
- castor_extractor-0.24.20.dist-info/METADATA,sha256=DvgjbhUmiYXzV9e3MXsEGuSfgOog38LrEBNmqFIAcyI,25213
431
- castor_extractor-0.24.20.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
432
- castor_extractor-0.24.20.dist-info/entry_points.txt,sha256=_F-qeZCybjoMkNb9ErEhnyqXuG6afHIFQhakdBHZsr4,1803
433
- castor_extractor-0.24.20.dist-info/RECORD,,
428
+ castor_extractor-0.24.21.dist-info/LICENCE,sha256=sL-IGa4hweyya1HgzMskrRdybbIa2cktzxb5qmUgDg8,8254
429
+ castor_extractor-0.24.21.dist-info/METADATA,sha256=Yg7Sgskg-uUeas31S1Uit1F7L1tPcVCLFy2U3rBlzIY,25312
430
+ castor_extractor-0.24.21.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
431
+ castor_extractor-0.24.21.dist-info/entry_points.txt,sha256=_F-qeZCybjoMkNb9ErEhnyqXuG6afHIFQhakdBHZsr4,1803
432
+ castor_extractor-0.24.21.dist-info/RECORD,,
@@ -1,6 +0,0 @@
1
- SCOPES = (
2
- "https://www.googleapis.com/auth/datastudio",
3
- "https://www.googleapis.com/auth/userinfo.profile",
4
- "https://www.googleapis.com/auth/admin.reports.audit.readonly",
5
- "https://www.googleapis.com/auth/admin.directory.user.readonly",
6
- )