etlplus 0.14.0__py3-none-any.whl → 0.14.1__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.
etlplus/ops/__init__.py CHANGED
@@ -4,10 +4,12 @@
4
4
  Data operations helpers.
5
5
 
6
6
  Importing :mod:`etlplus.ops` exposes the coarse-grained helpers most users care
7
- about: ``extract``, ``transform``, ``load``, ``validate``, and ``run``. Each
8
- helper delegates to the richer modules under ``etlplus.ops.*`` while
9
- presenting a compact public API surface. Conditional validation orchestration
10
- is available via :func:`etlplus.ops.utils.maybe_validate`.
7
+ about: ``extract``, ``transform``, ``load``, ``validate``, ``run``, and
8
+ ``run_pipeline``. Each helper delegates to the richer modules under
9
+ ``etlplus.ops.*`` while presenting a compact public API surface. Conditional
10
+ validation orchestration is available via
11
+ :func:`etlplus.ops.utils.maybe_validate`. The legacy compatibility module
12
+ :mod:`etlplus.ops.__init__validation` is deprecated in favor of this package.
11
13
 
12
14
  Examples
13
15
  --------
@@ -42,6 +44,7 @@ See Also
42
44
  from .extract import extract
43
45
  from .load import load
44
46
  from .run import run
47
+ from .run import run_pipeline
45
48
  from .transform import transform
46
49
  from .validate import validate
47
50
 
@@ -52,6 +55,7 @@ __all__ = [
52
55
  'extract',
53
56
  'load',
54
57
  'run',
58
+ 'run_pipeline',
55
59
  'transform',
56
60
  'validate',
57
61
  ]
etlplus/ops/run.py CHANGED
@@ -21,7 +21,12 @@ from ..api import compose_api_target_env
21
21
  from ..api import paginate_with_client
22
22
  from ..config import load_pipeline_config
23
23
  from ..enums import DataConnectorType
24
+ from ..enums import HttpMethod
25
+ from ..file import FileFormat
26
+ from ..types import JSONData
24
27
  from ..types import JSONDict
28
+ from ..types import PipelineConfig
29
+ from ..types import StrPath
25
30
  from ..types import Timeout
26
31
  from ..utils import print_json
27
32
  from .extract import extract
@@ -33,7 +38,11 @@ from .validate import validate
33
38
  # SECTION: EXPORTS ========================================================== #
34
39
 
35
40
 
36
- __all__ = ['run']
41
+ __all__ = [
42
+ # Functions
43
+ 'run',
44
+ 'run_pipeline',
45
+ ]
37
46
 
38
47
 
39
48
  # SECTION: CONSTANTS ======================================================== #
@@ -42,6 +51,38 @@ __all__ = ['run']
42
51
  DEFAULT_CONFIG_PATH: Final[str] = 'in/pipeline.yml'
43
52
 
44
53
 
54
+ # SECTION: INTERNAL FUNCTIONS =============================================== #
55
+
56
+
57
+ def _resolve_validation_config(
58
+ job_obj: Any,
59
+ cfg: Any,
60
+ ) -> tuple[bool, dict[str, Any], str, str]:
61
+ """
62
+ Resolve validation settings for a job with safe defaults.
63
+
64
+ Parameters
65
+ ----------
66
+ job_obj : Any
67
+ Job configuration object.
68
+ cfg : Any
69
+ Pipeline configuration object with validations.
70
+
71
+ Returns
72
+ -------
73
+ tuple[bool, dict[str, Any], str, str]
74
+ Tuple of (enabled, rules, severity, phase).
75
+ """
76
+ val_ref = job_obj.validate
77
+ if val_ref is None:
78
+ return False, {}, 'error', 'before_transform'
79
+
80
+ rules = cfg.validations.get(val_ref.ruleset, {})
81
+ severity = (val_ref.severity or 'error').lower()
82
+ phase = (val_ref.phase or 'before_transform').lower()
83
+ return True, rules, severity, phase
84
+
85
+
45
86
  # SECTION: FUNCTIONS ======================================================== #
46
87
 
47
88
 
@@ -174,19 +215,10 @@ def run(
174
215
  # keep explicit guard for defensive programming.
175
216
  raise ValueError(f'Unsupported source type: {stype_raw}')
176
217
 
177
- # DRY: unified validation helper (pre/post transform)
178
- val_ref = job_obj.validate
179
- enabled_validation = val_ref is not None
180
- if enabled_validation:
181
- # Type narrowing for static checkers
182
- assert val_ref is not None
183
- rules = cfg.validations.get(val_ref.ruleset, {})
184
- severity = (val_ref.severity or 'error').lower()
185
- phase = (val_ref.phase or 'before_transform').lower()
186
- else:
187
- rules = {}
188
- severity = 'error'
189
- phase = 'before_transform'
218
+ enabled_validation, rules, severity, phase = _resolve_validation_config(
219
+ job_obj,
220
+ cfg,
221
+ )
190
222
 
191
223
  # Pre-transform validation (if configured).
192
224
  data = maybe_validate(
@@ -272,3 +304,90 @@ def run(
272
304
  # Return the terminal load result directly; callers (e.g., CLI) can wrap
273
305
  # it in their own envelope when needed.
274
306
  return cast(JSONDict, result)
307
+
308
+
309
+ def run_pipeline(
310
+ *,
311
+ source_type: DataConnectorType | str | None = None,
312
+ source: StrPath | JSONData | None = None,
313
+ operations: PipelineConfig | None = None,
314
+ target_type: DataConnectorType | str | None = None,
315
+ target: StrPath | None = None,
316
+ file_format: FileFormat | str | None = None,
317
+ method: HttpMethod | str | None = None,
318
+ **kwargs: Any,
319
+ ) -> JSONData:
320
+ """
321
+ Run a single extract-transform-load flow without a YAML config.
322
+
323
+ Parameters
324
+ ----------
325
+ source_type : DataConnectorType | str | None, optional
326
+ Connector type for extraction. When ``None``, ``source`` is assumed
327
+ to be pre-loaded data and extraction is skipped.
328
+ source : StrPath | JSONData | None, optional
329
+ Data source for extraction or the pre-loaded payload when
330
+ ``source_type`` is ``None``.
331
+ operations : PipelineConfig | None, optional
332
+ Transform configuration passed to :func:`etlplus.ops.transform`.
333
+ target_type : DataConnectorType | str | None, optional
334
+ Connector type for loading. When ``None``, load is skipped and the
335
+ transformed data is returned.
336
+ target : StrPath | None, optional
337
+ Target for loading (file path, connection string, or API URL).
338
+ file_format : FileFormat | str | None, optional
339
+ File format for file sources/targets (forwarded to extract/load).
340
+ method : HttpMethod | str | None, optional
341
+ HTTP method for API loads (forwarded to :func:`etlplus.ops.load`).
342
+ **kwargs : Any
343
+ Extra keyword arguments forwarded to extract/load for API options
344
+ (headers, timeout, session, etc.).
345
+
346
+ Returns
347
+ -------
348
+ JSONData
349
+ Transformed data or the load result payload.
350
+
351
+ Raises
352
+ ------
353
+ TypeError
354
+ Raised when extracted data is not a dict or list of dicts and no
355
+ target is specified.
356
+ ValueError
357
+ Raised when required source/target inputs are missing.
358
+ """
359
+ if source_type is None:
360
+ if source is None:
361
+ raise ValueError('source or source_type is required')
362
+ data = source
363
+ else:
364
+ if source is None:
365
+ raise ValueError('source is required when source_type is set')
366
+ data = extract(
367
+ source_type,
368
+ cast(StrPath, source),
369
+ file_format=file_format,
370
+ **kwargs,
371
+ )
372
+
373
+ if operations:
374
+ data = transform(data, operations)
375
+
376
+ if target_type is None:
377
+ if not isinstance(data, (dict, list)):
378
+ raise TypeError(
379
+ f'Expected data to be dict or list of dicts, '
380
+ f'got {type(data).__name__}',
381
+ )
382
+ return data
383
+ if target is None:
384
+ raise ValueError('target is required when target_type is set')
385
+
386
+ return load(
387
+ data,
388
+ target_type,
389
+ target,
390
+ file_format=file_format,
391
+ method=method,
392
+ **kwargs,
393
+ )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: etlplus
3
- Version: 0.14.0
3
+ Version: 0.14.1
4
4
  Summary: A Swiss Army knife for simple ETL operations
5
5
  Home-page: https://github.com/Dagitali/ETLPlus
6
6
  Author: ETLPlus Team
@@ -115,10 +115,10 @@ etlplus/file/yaml.py,sha256=8BEqCELaTQ_nRu1iksLBHVj19P6JmcUf5__fe0yVigw,2449
115
115
  etlplus/file/zip.py,sha256=nd26V3S0edklriKnKOGDTLlO8RBXTda_zLLEQrJgKL4,4185
116
116
  etlplus/file/zsav.py,sha256=2WxjXamvzj0adDbWGMWM3-cj_LsCRjyZz4J907lNkPk,1664
117
117
  etlplus/ops/README.md,sha256=8omi7DYZhelc26JKk8Cm8QR8I3OGwziysPj1ivx41iQ,1380
118
- etlplus/ops/__init__.py,sha256=43nKiR5aWhR3rcpLfluzA972vX7V5DPKvzU7y0XmFJQ,1524
118
+ etlplus/ops/__init__.py,sha256=NIIr2f-AZj5B0piBt6gjv46Yn0SzGYxEe6BPoopRh38,1702
119
119
  etlplus/ops/extract.py,sha256=s3CaLXMY_loMoPU47rvvzyp1buk84uCzDqqaI7l3Dwg,5785
120
120
  etlplus/ops/load.py,sha256=2jMewdjaNS1GKZ9cn94ISRSzDfqO3_s5fb_YNo_CqIc,8330
121
- etlplus/ops/run.py,sha256=u-YUh6ht_jtPHN4d0-ybH6yn4UboNfTKZ7RrBwfM5-A,9829
121
+ etlplus/ops/run.py,sha256=nivgj3cY5QniNc-u4n71gr2p4wXXvt5fYQUHiOEfKUA,13395
122
122
  etlplus/ops/transform.py,sha256=1P43WYUaw872JDU86FhbbbkP8xnBWpgEPn2Q-z4ywls,25421
123
123
  etlplus/ops/utils.py,sha256=9cN-bmcYs87R84GllmW7fSiUEmXFqIkGbSFiPYStsbA,11198
124
124
  etlplus/ops/validate.py,sha256=gLa5zcwhxGbaIhH-OqTwDsQAgAYZSajLVGwwyeT2OZk,13257
@@ -126,9 +126,9 @@ etlplus/templates/README.md,sha256=kHSZ8FWcrlrcWz0hBIbho-k1Bi-PL-DQ7g02o-g70c8,1
126
126
  etlplus/templates/__init__.py,sha256=tsniN7XJYs3NwYxJ6c2HD5upHP3CDkLx-bQCMt97UOM,106
127
127
  etlplus/templates/ddl.sql.j2,sha256=s8fMWvcb4eaJVXkifuib1aQPljtZ8buuyB_uA-ZdU3Q,4734
128
128
  etlplus/templates/view.sql.j2,sha256=Iy8DHfhq5yyvrUKDxqp_aHIEXY4Tm6j4wT7YDEFWAhk,2180
129
- etlplus-0.14.0.dist-info/licenses/LICENSE,sha256=MuNO63i6kWmgnV2pbP2SLqP54mk1BGmu7CmbtxMmT-U,1069
130
- etlplus-0.14.0.dist-info/METADATA,sha256=gKu31Fe8g5vk461qZsuqwsetPGKENRGwDIH2bbk4PxA,28115
131
- etlplus-0.14.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
132
- etlplus-0.14.0.dist-info/entry_points.txt,sha256=6w-2-jzuPa55spzK34h-UKh2JTEShh38adFRONNP9QE,45
133
- etlplus-0.14.0.dist-info/top_level.txt,sha256=aWWF-udn_sLGuHTM6W6MLh99ArS9ROkUWO8Mi8y1_2U,8
134
- etlplus-0.14.0.dist-info/RECORD,,
129
+ etlplus-0.14.1.dist-info/licenses/LICENSE,sha256=MuNO63i6kWmgnV2pbP2SLqP54mk1BGmu7CmbtxMmT-U,1069
130
+ etlplus-0.14.1.dist-info/METADATA,sha256=hr3LS7VVswkiW_PnXQcHZFEElSZFrrgVxi5BhkKz5h8,28115
131
+ etlplus-0.14.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
132
+ etlplus-0.14.1.dist-info/entry_points.txt,sha256=6w-2-jzuPa55spzK34h-UKh2JTEShh38adFRONNP9QE,45
133
+ etlplus-0.14.1.dist-info/top_level.txt,sha256=aWWF-udn_sLGuHTM6W6MLh99ArS9ROkUWO8Mi8y1_2U,8
134
+ etlplus-0.14.1.dist-info/RECORD,,