dlt-utils 0.7.2__tar.gz → 0.7.3__tar.gz

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dlt_utils
3
- Version: 0.7.2
3
+ Version: 0.7.3
4
4
  Summary: Shared utilities for dlt data pipelines with multi-company support
5
5
  Author: Jay van den Bos
6
6
  License: MIT
@@ -45,7 +45,7 @@ from .pipeline import (
45
45
  )
46
46
 
47
47
 
48
- __version__ = "0.7.2"
48
+ __version__ = "0.7.3"
49
49
 
50
50
  __all__ = [
51
51
  # Incremental
@@ -23,14 +23,14 @@ def validate_refresh_args(
23
23
  ) -> None:
24
24
  """
25
25
  Validate that refresh arguments are used correctly.
26
-
26
+
27
27
  Raises ValueError if drop_sources is used with a resource filter,
28
28
  as this would drop ALL tables but only reload selected resources.
29
-
29
+
30
30
  Args:
31
31
  refresh: The refresh mode ('drop_sources' or 'drop_resources').
32
32
  resources_filter: List of resources being loaded (None = all).
33
-
33
+
34
34
  Raises:
35
35
  ValueError: If drop_sources is used with a resource filter.
36
36
  """
@@ -49,46 +49,47 @@ def filter_resources(
49
49
  ) -> list[str]:
50
50
  """
51
51
  Filter available resources based on requested resources.
52
-
52
+
53
53
  Args:
54
54
  available_resources: List of all available resource names.
55
55
  requested_resources: List of requested resources (None = all).
56
-
56
+
57
57
  Returns:
58
58
  List of valid resources to load.
59
-
59
+
60
60
  Raises:
61
61
  ValueError: If no valid resources are found.
62
62
  """
63
63
  if requested_resources is None:
64
64
  return available_resources
65
-
66
- valid_resources = [r for r in requested_resources if r in available_resources]
67
-
65
+
66
+ valid_resources = [
67
+ r for r in requested_resources if r in available_resources]
68
+
68
69
  if not valid_resources:
69
70
  raise ValueError(
70
71
  f"No valid resources found. "
71
72
  f"Requested: {requested_resources}. "
72
73
  f"Available: {available_resources}"
73
74
  )
74
-
75
+
75
76
  # Log any requested resources that weren't found
76
77
  invalid = set(requested_resources) - set(valid_resources)
77
78
  if invalid:
78
79
  logger.warning(f"Ignored invalid resources: {invalid}")
79
-
80
+
80
81
  return valid_resources
81
82
 
82
83
 
83
84
  def print_resources(source: Any) -> None:
84
85
  """
85
86
  Print available resources from a dlt source and exit.
86
-
87
+
87
88
  Args:
88
89
  source: A dlt source object with a resources attribute.
89
90
  """
90
91
  available_resources = sorted(get_resource_names(source))
91
-
92
+
92
93
  print("\nAvailable resources:")
93
94
  print("-" * 40)
94
95
  for resource in available_resources:
@@ -100,10 +101,10 @@ def print_resources(source: Any) -> None:
100
101
  def get_resource_names(source: Any) -> list[str]:
101
102
  """
102
103
  Get list of resource names from a dlt source.
103
-
104
+
104
105
  Args:
105
106
  source: A dlt source object with a resources attribute.
106
-
107
+
107
108
  Returns:
108
109
  List of resource names.
109
110
  """
@@ -113,20 +114,20 @@ def get_resource_names(source: Any) -> list[str]:
113
114
  def mask_sensitive_value(value: str | None, show_chars: int = 2) -> str:
114
115
  """
115
116
  Mask a sensitive value (like API key) showing only first and middle characters.
116
-
117
+
117
118
  Args:
118
119
  value: The value to mask.
119
120
  show_chars: Number of characters to show at start and middle.
120
-
121
+
121
122
  Returns:
122
123
  Masked value like "ab..cd..***" or "N/A" if not set.
123
124
  """
124
125
  if not value:
125
126
  return "N/A"
126
-
127
+
127
128
  if len(value) < 6:
128
129
  return value[:1] + "***"
129
-
130
+
130
131
  mid = len(value) // 2
131
132
  return f"{value[:show_chars]}..{value[mid:mid+show_chars]}..***"
132
133
 
@@ -138,34 +139,34 @@ def cleanup_tombstones(
138
139
  ) -> None:
139
140
  """
140
141
  Clean up tombstone records from tables after a successful pipeline run.
141
-
142
+
142
143
  Tombstones are placeholder records used to ensure delete-insert semantics
143
144
  work correctly for partitions that have no real data. After the pipeline
144
145
  completes, these tombstone records should be removed.
145
-
146
+
146
147
  Args:
147
148
  pipeline: A dlt pipeline object with sql_client() method.
148
149
  resources: List of resource/table names to clean tombstones from.
149
150
  column_name: The boolean column name that marks tombstone records.
150
151
  Defaults to "_tt_is_tombstone".
151
-
152
+
152
153
  Example:
153
154
  # Clean up tombstones from all resources except 'customer'
154
155
  tombstone_resources = [r for r in sync_resources if r != "customer"]
155
156
  cleanup_tombstones(pipeline, tombstone_resources)
156
-
157
+
157
158
  # Clean up with a custom column name
158
159
  cleanup_tombstones(pipeline, ["my_table"], column_name="is_tombstone")
159
160
  """
160
161
  if not resources:
161
162
  logger.debug("No resources provided for tombstone cleanup")
162
163
  return
163
-
164
+
164
165
  with pipeline.sql_client() as sql_client:
165
166
  for resource_name in resources:
166
167
  table_name = sql_client.make_qualified_table_name(resource_name)
167
168
  delete_query = f"DELETE FROM {table_name} WHERE {column_name} = 1"
168
-
169
+
169
170
  try:
170
171
  sql_client.execute_sql(delete_query)
171
172
  logger.info(f"Cleaned up tombstone records from {table_name}")
@@ -267,11 +268,12 @@ def print_configs(
267
268
  configs: Sequence of dataclass instances to print.
268
269
  title: Title for the table header.
269
270
  columns: List of (field_name, header_label, width) tuples defining which
270
- fields to display and how. If None, all fields are shown with
271
- auto-generated headers.
272
- sensitive_fields: List of field names that contain sensitive data to mask.
271
+ fields to display and how. If None, all fields are shown with
272
+ auto-generated headers.
273
+ sensitive_fields: List of field names that contain sensitive data to mask. Uses
274
+ auto-detection for dataclass fields with repr=False if not provided.
273
275
  mask_func: Function to mask sensitive values. If None, uses mask_sensitive_value
274
- which shows first and middle characters.
276
+ which shows first and middle characters.
275
277
 
276
278
  Example:
277
279
  print_configs(
@@ -302,8 +304,17 @@ def print_configs(
302
304
  "columns must be provided for non-dataclass configs"
303
305
  )
304
306
 
305
- sensitive_fields = sensitive_fields or []
306
-
307
+ auto_sensitive_fields: set[str] = set()
308
+ if is_dataclass(configs[0]):
309
+ auto_sensitive_fields = {
310
+ f.name for f in fields(configs[0]) if not f.repr
311
+ }
312
+
313
+ if sensitive_fields is None:
314
+ sensitive_fields = list(auto_sensitive_fields)
315
+ else:
316
+ sensitive_fields = list(set(sensitive_fields) | auto_sensitive_fields)
317
+
307
318
  # Use mask_sensitive_value as default mask function
308
319
  if mask_func is None:
309
320
  mask_func = mask_sensitive_value
@@ -315,11 +326,11 @@ def print_configs(
315
326
  # Print header
316
327
  print(f"\n{title}:")
317
328
  print("-" * total_width)
318
-
329
+
319
330
  header = f"{'Index':<{index_width}}"
320
331
  header += "".join(f"{label:<{width}}" for _, label, width in columns)
321
332
  print(header)
322
-
333
+
323
334
  print("-" * total_width)
324
335
 
325
336
  # Print rows
@@ -327,12 +338,12 @@ def print_configs(
327
338
  row = f"{i:<{index_width}}"
328
339
  for field_name, _, width in columns:
329
340
  value = getattr(config, field_name, None)
330
-
341
+
331
342
  if field_name in sensitive_fields:
332
343
  display_value = mask_func(value)
333
344
  else:
334
345
  display_value = str(value) if value is not None else "N/A"
335
-
346
+
336
347
  row += f"{display_value:<{width}}"
337
348
  print(row)
338
349
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dlt_utils
3
- Version: 0.7.2
3
+ Version: 0.7.3
4
4
  Summary: Shared utilities for dlt data pipelines with multi-company support
5
5
  Author: Jay van den Bos
6
6
  License: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "dlt_utils"
7
- version = "0.7.2"
7
+ version = "0.7.3"
8
8
  description = "Shared utilities for dlt data pipelines with multi-company support"
9
9
  readme = "README.md"
10
10
  license = { text = "MIT" }
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes