etlplus 0.12.12__py3-none-any.whl → 0.15.0__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.
Files changed (50) hide show
  1. etlplus/README.md +2 -2
  2. etlplus/__init__.py +1 -26
  3. etlplus/api/README.md +2 -2
  4. etlplus/api/__init__.py +10 -0
  5. etlplus/api/config.py +36 -20
  6. etlplus/api/endpoint_client.py +3 -3
  7. etlplus/api/enums.py +51 -0
  8. etlplus/api/pagination/client.py +1 -1
  9. etlplus/api/rate_limiting/config.py +13 -1
  10. etlplus/api/rate_limiting/rate_limiter.py +8 -11
  11. etlplus/api/request_manager.py +11 -6
  12. etlplus/api/transport.py +14 -2
  13. etlplus/api/types.py +7 -6
  14. etlplus/{run_helpers.py → api/utils.py} +209 -153
  15. etlplus/cli/README.md +2 -2
  16. etlplus/cli/handlers.py +19 -9
  17. etlplus/config/README.md +31 -33
  18. etlplus/config/__init__.py +9 -32
  19. etlplus/config/types.py +0 -64
  20. etlplus/dag.py +103 -0
  21. etlplus/database/README.md +2 -2
  22. etlplus/enums.py +0 -32
  23. etlplus/file/README.md +2 -2
  24. etlplus/file/enums.py +1 -1
  25. etlplus/{validation → ops}/README.md +2 -2
  26. etlplus/ops/__init__.py +61 -0
  27. etlplus/{extract.py → ops/extract.py} +78 -94
  28. etlplus/{load.py → ops/load.py} +73 -93
  29. etlplus/{run.py → ops/run.py} +153 -118
  30. etlplus/{transform.py → ops/transform.py} +75 -68
  31. etlplus/{validation → ops}/utils.py +80 -15
  32. etlplus/{validate.py → ops/validate.py} +19 -9
  33. etlplus/templates/README.md +2 -2
  34. etlplus/types.py +2 -2
  35. etlplus/workflow/README.md +52 -0
  36. etlplus/workflow/__init__.py +43 -0
  37. etlplus/{config → workflow}/connector.py +17 -16
  38. etlplus/workflow/dag.py +105 -0
  39. etlplus/{config → workflow}/jobs.py +31 -15
  40. etlplus/{config → workflow}/pipeline.py +11 -3
  41. etlplus/{config → workflow}/profile.py +8 -5
  42. etlplus/workflow/types.py +115 -0
  43. {etlplus-0.12.12.dist-info → etlplus-0.15.0.dist-info}/METADATA +91 -60
  44. {etlplus-0.12.12.dist-info → etlplus-0.15.0.dist-info}/RECORD +49 -43
  45. {etlplus-0.12.12.dist-info → etlplus-0.15.0.dist-info}/WHEEL +1 -1
  46. etlplus/validation/__init__.py +0 -44
  47. /etlplus/{config → workflow}/utils.py +0 -0
  48. {etlplus-0.12.12.dist-info → etlplus-0.15.0.dist-info}/entry_points.txt +0 -0
  49. {etlplus-0.12.12.dist-info → etlplus-0.15.0.dist-info}/licenses/LICENSE +0 -0
  50. {etlplus-0.12.12.dist-info → etlplus-0.15.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,115 @@
1
+ """
2
+ :mod:`etlplus.workflow.types` module.
3
+
4
+ Type aliases and editor-only :class:`TypedDict`s for :mod:`etlplus.config`.
5
+
6
+ These types improve IDE autocomplete and static analysis while the runtime
7
+ parsers remain permissive.
8
+
9
+ Notes
10
+ -----
11
+ - TypedDicts in this module are intentionally ``total=False`` and are not
12
+ enforced at runtime.
13
+ - :meth:`*.from_obj` constructors accept :class:`Mapping[str, Any]` and perform
14
+ tolerant parsing and light casting. This keeps the runtime permissive while
15
+ improving autocomplete and static analysis for contributors.
16
+
17
+ Examples
18
+ --------
19
+ >>> from etlplus.workflow import Connector
20
+ >>> src: Connector = {
21
+ >>> "type": "file",
22
+ >>> "path": "/data/input.csv",
23
+ >>> }
24
+ >>> tgt: Connector = {
25
+ >>> "type": "database",
26
+ >>> "connection_string": "postgresql://user:pass@localhost/db",
27
+ >>> }
28
+ >>> from etlplus.api import RetryPolicy
29
+ >>> rp: RetryPolicy = {"max_attempts": 3, "backoff": 0.5}
30
+ """
31
+
32
+ from __future__ import annotations
33
+
34
+ from typing import Literal
35
+ from typing import TypedDict
36
+
37
+ from ..api import PaginationConfigMap
38
+ from ..api import RateLimitConfigMap
39
+ from ..types import StrAnyMap
40
+
41
+ # SECTION: EXPORTS ========================================================= #
42
+
43
+
44
+ __all__ = [
45
+ # Type Aliases
46
+ 'ConnectorType',
47
+ # Typed Dicts
48
+ 'ConnectorApiConfigMap',
49
+ 'ConnectorDbConfigMap',
50
+ 'ConnectorFileConfigMap',
51
+ ]
52
+
53
+
54
+ # SECTION: TYPE ALIASES ===================================================== #
55
+
56
+
57
+ # Literal type for supported connector kinds
58
+ type ConnectorType = Literal['api', 'database', 'file']
59
+
60
+
61
+ # SECTION: TYPED DICTS ====================================================== #
62
+
63
+
64
+ class ConnectorApiConfigMap(TypedDict, total=False):
65
+ """
66
+ Shape accepted by :meth:`ConnectorApi.from_obj` (all keys optional).
67
+
68
+ See Also
69
+ --------
70
+ - :meth:`etlplus.workflow.connector.ConnectorApi.from_obj`
71
+ """
72
+
73
+ name: str
74
+ type: ConnectorType
75
+ url: str
76
+ method: str
77
+ headers: StrAnyMap
78
+ query_params: StrAnyMap
79
+ pagination: PaginationConfigMap
80
+ rate_limit: RateLimitConfigMap
81
+ api: str
82
+ endpoint: str
83
+
84
+
85
+ class ConnectorDbConfigMap(TypedDict, total=False):
86
+ """
87
+ Shape accepted by :meth:`ConnectorDb.from_obj` (all keys optional).
88
+
89
+ See Also
90
+ --------
91
+ - :meth:`etlplus.workflow.connector.ConnectorDb.from_obj`
92
+ """
93
+
94
+ name: str
95
+ type: ConnectorType
96
+ connection_string: str
97
+ query: str
98
+ table: str
99
+ mode: str
100
+
101
+
102
+ class ConnectorFileConfigMap(TypedDict, total=False):
103
+ """
104
+ Shape accepted by :meth:`ConnectorFile.from_obj` (all keys optional).
105
+
106
+ See Also
107
+ --------
108
+ - :meth:`etlplus.workflow.connector.ConnectorFile.from_obj`
109
+ """
110
+
111
+ name: str
112
+ type: ConnectorType
113
+ format: str
114
+ path: str
115
+ options: StrAnyMap
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: etlplus
3
- Version: 0.12.12
3
+ Version: 0.15.0
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
@@ -79,8 +79,10 @@ package and command-line interface for data extraction, validation, transformati
79
79
  - [Binary Serialization and Interchange](#binary-serialization-and-interchange)
80
80
  - [Databases and Embedded Storage](#databases-and-embedded-storage)
81
81
  - [Spreadsheets](#spreadsheets)
82
- - [Data Archives](#data-archives)
82
+ - [Statistical / Scientific / Numeric Computing](#statistical--scientific--numeric-computing)
83
83
  - [Logs and Event Streams](#logs-and-event-streams)
84
+ - [Data Archives](#data-archives)
85
+ - [Templates](#templates)
84
86
  - [Usage](#usage)
85
87
  - [Command Line Interface](#command-line-interface)
86
88
  - [Argument Order and Required Options](#argument-order-and-required-options)
@@ -194,7 +196,7 @@ etlplus extract file examples/data/sample.csv \
194
196
  [Python API](#python-api):
195
197
 
196
198
  ```python
197
- from etlplus import extract, transform, validate, load
199
+ from etlplus.ops import extract, transform, validate, load
198
200
 
199
201
  data = extract("file", "input.csv")
200
202
  ops = {"filter": {"field": "age", "op": "gt", "value": 25}, "select": ["name", "email"]}
@@ -221,93 +223,122 @@ DDL can be rendered from table specs for migrations or schema checks.
221
223
 
222
224
  ### Files (`file`)
223
225
 
224
- File formats are grouped as in `FileFormat`. Support is marked as:
226
+ Recognized file formats are listed in the tables below. Support for reading to or writing from a recognized file format is marked as:
225
227
 
226
228
  - **Y**: implemented (may require optional dependencies)
227
229
  - **N**: stubbed or not yet implemented
228
230
 
229
231
  #### Stubbed / Placeholder
230
232
 
231
- | Format | Supported | Description |
232
- | --- | --- | --- |
233
+ | Format | Read | Write | Description |
234
+ | --- | --- | --- | --- |
233
235
  | `stub` | N | Placeholder format for tests and future connectors. |
234
236
 
235
237
  #### Tabular & Delimited Text
236
238
 
237
- | Format | Supported | Description |
238
- | --- | --- | --- |
239
- | `csv` | Y | Comma-Separated Values |
240
- | `fwf` | N | Fixed-Width Fields |
241
- | `dat` | N | Generic data file, often delimited or fixed-width |
242
- | `psv` | N | Pipe-Separated Values |
243
- | `tab` | N | Often synonymous with TSV |
244
- | `tsv` | Y | Tab-Separated Values |
245
- | `txt` | Y | Plain text, often delimited or fixed-width |
239
+ | Format | Read | Write | Description |
240
+ | --- | --- | --- | --- |
241
+ | `csv` | Y | Y | Comma-Separated Values |
242
+ | `dat` | N | N | Generic data file, often delimited or fixed-width |
243
+ | `fwf` | N | N | Fixed-Width Fields |
244
+ | `psv` | N | N | Pipe-Separated Values |
245
+ | `tab` | N | N | Often synonymous with TSV |
246
+ | `tsv` | Y | Y | Tab-Separated Values |
247
+ | `txt` | Y | Y | Plain text, often delimited or fixed-width |
246
248
 
247
249
  #### Semi-Structured Text
248
250
 
249
- | Format | Supported | Description |
250
- | --- | --- | --- |
251
- | `cfg` | N | Config-style key-value pairs |
252
- | `conf` | N | Config-style key-value pairs |
253
- | `ini` | N | Config-style key-value pairs |
254
- | `json` | Y | JavaScript Object Notation |
255
- | `ndjson` | Y | Newline-Delimited JSON |
256
- | `properties` | N | Java-style key-value pairs |
257
- | `toml` | N | Tom's Obvious Minimal Language |
258
- | `xml` | Y | Extensible Markup Language |
259
- | `yaml` | Y | YAML Ain't Markup Language |
251
+ | Format | Read | Write | Description |
252
+ | --- | --- | --- | --- |
253
+ | `cfg` | N | N | Config-style key-value pairs |
254
+ | `conf` | N | N | Config-style key-value pairs |
255
+ | `ini` | N | N | Config-style key-value pairs |
256
+ | `json` | Y | Y | JavaScript Object Notation |
257
+ | `ndjson` | Y | Y | Newline-Delimited JSON |
258
+ | `properties` | N | N | Java-style key-value pairs |
259
+ | `toml` | N | N | Tom's Obvious Minimal Language |
260
+ | `xml` | Y | Y | Extensible Markup Language |
261
+ | `yaml` | Y | Y | YAML Ain't Markup Language |
260
262
 
261
263
  #### Columnar / Analytics-Friendly
262
264
 
263
- | Format | Supported | Description |
264
- | --- | --- | --- |
265
- | `arrow` | N | Apache Arrow IPC |
266
- | `feather` | Y | Apache Arrow Feather |
267
- | `orc` | Y | Optimized Row Columnar; common in Hadoop |
268
- | `parquet` | Y | Apache Parquet; common in Big Data |
265
+ | Format | Read | Write | Description |
266
+ | --- | --- | --- | --- |
267
+ | `arrow` | N | N | Apache Arrow IPC |
268
+ | `feather` | Y | Y | Apache Arrow Feather |
269
+ | `orc` | Y | Y | Optimized Row Columnar; common in Hadoop |
270
+ | `parquet` | Y | Y | Apache Parquet; common in Big Data |
269
271
 
270
272
  #### Binary Serialization and Interchange
271
273
 
272
- | Format | Supported | Description |
273
- | --- | --- | --- |
274
- | `avro` | Y | Apache Avro |
275
- | `bson` | N | Binary JSON; common with MongoDB exports/dumps |
276
- | `cbor` | N | Concise Binary Object Representation |
277
- | `ion` | N | Amazon Ion |
278
- | `msgpack` | N | MessagePack |
279
- | `pb` | N | Protocol Buffers (Google Protobuf) |
280
- | `pbf` | N | Protocolbuffer Binary Format; often for GIS data |
281
- | `proto` | N | Protocol Buffers schema; often in .pb / .bin |
274
+ | Format | Read | Write | Description |
275
+ | --- | --- | --- | --- |
276
+ | `avro` | Y | Y | Apache Avro |
277
+ | `bson` | N | N | Binary JSON; common with MongoDB exports/dumps |
278
+ | `cbor` | N | N | Concise Binary Object Representation |
279
+ | `ion` | N | N | Amazon Ion |
280
+ | `msgpack` | N | N | MessagePack |
281
+ | `pb` | N | N | Protocol Buffers (Google Protobuf) |
282
+ | `pbf` | N | N | Protocolbuffer Binary Format; often for GIS data |
283
+ | `proto` | N | N | Protocol Buffers schema; often in .pb / .bin |
282
284
 
283
285
  #### Databases and Embedded Storage
284
286
 
285
- | Format | Supported | Description |
286
- | --- | --- | --- |
287
- | `accdb` | N | Microsoft Access database file (newer format) |
288
- | `duckdb` | N | DuckDB database file |
289
- | `mdb` | N | Microsoft Access database file (older format) |
290
- | `sqlite` | N | SQLite database file |
287
+ | Format | Read | Write | Description |
288
+ | --- | --- | --- | --- |
289
+ | `accdb` | N | N | Microsoft Access (newer format) |
290
+ | `duckdb` | N | N | DuckDB |
291
+ | `mdb` | N | N | Microsoft Access (older format) |
292
+ | `sqlite` | N | N | SQLite |
291
293
 
292
294
  #### Spreadsheets
293
295
 
296
+ | Format | Read | Write | Description |
297
+ | --- | --- | --- | --- |
298
+ | `numbers` | N | N | Apple Numbers |
299
+ | `ods` | N | N | OpenDocument |
300
+ | `wks` | N | N | Lotus 1-2-3 |
301
+ | `xls` | Y | Y | Microsoft Excel (BIFF) |
302
+ | `xlsm` | N | N | Microsoft Excel Macro-Enabled (Open XML) |
303
+ | `xlsx` | Y | Y | Microsoft Excel (Open XML) |
304
+
305
+ #### Statistical / Scientific / Numeric Computing
306
+
307
+ | Format | Read | Write | Description |
308
+ | --- | --- | --- | --- |
309
+ | `dta` | N | N | Stata |
310
+ | `hdf5` | N | N | Hierarchical Data Format |
311
+ | `mat` | N | N | MATLAB |
312
+ | `nc` | N | N | NetCDF |
313
+ | `rda` | N | N | RData workspace/object |
314
+ | `rds` | N | N | R data |
315
+ | `sas7bdat` | N | N | SAS data |
316
+ | `sav` | N | N | SPSS data |
317
+ | `sylk` | N | N | Symbolic Link |
318
+ | `xpt` | N | N | SAS Transport |
319
+ | `zsav` | N | N | Compressed SPSS data |
320
+
321
+ #### Logs and Event Streams
322
+
294
323
  | Format | Supported | Description |
295
324
  | --- | --- | --- |
296
- | `xls` | Y | Microsoft Excel (BIFF); read-only |
297
- | `xlsx` | Y | Microsoft Excel (Open XML) |
325
+ | `log` | N | N | Generic log file |
298
326
 
299
327
  #### Data Archives
300
328
 
301
- | Format | Supported | Description |
302
- | --- | --- | --- |
303
- | `gz` | Y | Gzip-compressed file |
304
- | `zip` | Y | ZIP archive |
329
+ | Format | Read | Write | Description |
330
+ | --- | --- | --- | --- |
331
+ | `gz` | Y | Y | Gzip-compressed file |
332
+ | `zip` | Y | Y | ZIP archive |
305
333
 
306
- #### Logs and Event Streams
334
+ #### Templates
307
335
 
308
- | Format | Supported | Description |
309
- | --- | --- | --- |
310
- | `log` | N | Generic log file |
336
+ | Format | Read | Write | Description |
337
+ | --- | --- | --- | --- |
338
+ | `hbs` | N | N | Handlebars |
339
+ | `jinja2` | N | N | Jinja2 |
340
+ | `mustache` | N | N | Mustache |
341
+ | `vm` | N | N | Apache Velocity |
311
342
 
312
343
  ## Usage
313
344
 
@@ -500,7 +531,7 @@ cat examples/data/sample.json \
500
531
  Use ETLPlus as a Python library:
501
532
 
502
533
  ```python
503
- from etlplus import extract, validate, transform, load
534
+ from etlplus.ops import extract, validate, transform, load
504
535
 
505
536
  # Extract data
506
537
  data = extract("file", "data.json")
@@ -695,7 +726,7 @@ We split tests into two layers:
695
726
  pagination + rate limit defaults, file/API connector interactions) may touch temp files and use
696
727
  fake clients.
697
728
 
698
- If a test calls `etlplus.cli.main()` or `etlplus.run.run()` it’s integration by default. Full
729
+ If a test calls `etlplus.cli.main()` or `etlplus.ops.run.run()` it’s integration by default. Full
699
730
  criteria: [`CONTRIBUTING.md#testing`](CONTRIBUTING.md#testing).
700
731
 
701
732
  ### Code Coverage
@@ -1,61 +1,53 @@
1
- etlplus/README.md,sha256=5jNes37UIy_THNmUr5HSAyS5mTCTa5tqRfEPnvsgV4s,1455
2
- etlplus/__init__.py,sha256=M2gScnyir6WOMAh_EuoQIiAzdcTls0_5hbd_Q6of8I0,1021
1
+ etlplus/README.md,sha256=NwnsMajz2_afAXgYDnTIwVU6uBoOKQn8f6UJHUY-Xe8,1461
2
+ etlplus/__init__.py,sha256=mgTP4PJmRmsEjTCAizzzdtzAmhuHtarmPzphzdjvLgM,277
3
3
  etlplus/__main__.py,sha256=btoROneNiigyfBU7BSzPKZ1R9gzBMpxcpsbPwmuHwTM,479
4
4
  etlplus/__version__.py,sha256=1E0GMK_yUWCMQFKxXjTvyMwofi0qT2k4CDNiHWiymWE,327
5
- etlplus/enums.py,sha256=WyxpUEUPdYdXlueKDXGaSEo7o9OqCXyzjDOOPqmW8tw,8326
6
- etlplus/extract.py,sha256=LOyL8_KCOaIGemTxSnKbN_ttfLWUljqT4OQxANe7G3k,6089
7
- etlplus/load.py,sha256=aufl-2CpuI_J1hKBY1uFsoVf9Gfl9bKQjs233dYFf00,8631
5
+ etlplus/dag.py,sha256=4EYmBsJax3y4clHv10jjdp3GrBBD_WblvtxUb_JxGCQ,2464
6
+ etlplus/enums.py,sha256=ZxObavNilITJNT4Mf2hBy1s4kKtTFUTmrc8_whkxKNg,7541
8
7
  etlplus/mixins.py,sha256=ifGpHwWv7U00yqGf-kN93vJax2IiK4jaGtTsPsO3Oak,1350
9
8
  etlplus/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
- etlplus/run.py,sha256=FjcMF56HUbSw2PAvB_dZWP-xTFP-Pa_QLYTsrjmFurw,12262
11
- etlplus/run_helpers.py,sha256=bj6MkaeFxjl3CeKG1HoXKx5DwAlXNERVW-GX-z1P_qQ,24373
12
- etlplus/transform.py,sha256=uAUVDDHYCgx7GpVez9IK3OAZM-CnCuMa9iox3vwGGJA,25296
13
- etlplus/types.py,sha256=1hsDlnF6r76zAwaUYay-i6pCM-Y0IU5nP7Crj8PLCQ4,6157
9
+ etlplus/types.py,sha256=LhyKU67CW7CcLEshE_1OIvEqWr-QVMJVYByf1221miY,6161
14
10
  etlplus/utils.py,sha256=BMLTWAvCJj3zLEcffBgURYnu0UGhhXsfH2WWpAt7fV8,13363
15
- etlplus/validate.py,sha256=7rJoEI_SIILdPpoBqqh2UJqg9oeReDz34mYSlc3t7Qg,12989
16
- etlplus/api/README.md,sha256=aGTbcL-EqaiMTS7GToibmeTIzjX-viP2OtUDfIJnZEo,7913
17
- etlplus/api/__init__.py,sha256=P2JUYFy6Ep4t6xnsBiCBfQCkQLHYYhA-yXPXCobS8Y0,4295
11
+ etlplus/api/README.md,sha256=Glxz9Y5RagqJomCPc8q3Nagm-23Owj9aAd8fM0H-Ph8,7917
12
+ etlplus/api/__init__.py,sha256=PK2lQv1FbsE7ZZS_ejevFZQSuOUHGApBc22YfHAzMqA,4615
18
13
  etlplus/api/auth.py,sha256=GOO5on-LoMS1GXTAhtK9rFcfpjbBcNeA6NE5UZwIq0g,12158
19
- etlplus/api/config.py,sha256=wRpOaZ31sPReVzEMme0jKl_37nqgraESwuYSNxP_xDo,17397
20
- etlplus/api/endpoint_client.py,sha256=PxCvBsvFhTIjEbY6drIIvciynHXQEvKu47Pi63Gxwqs,30693
14
+ etlplus/api/config.py,sha256=Xi1_FUaogQxAAx7LUTGwYr5vEB_SIFvjU_xgMGF2Fsc,17913
15
+ etlplus/api/endpoint_client.py,sha256=OPAvw3NkpSzeITqgRP1reyqX9Nc_XC8lAj6Yp7nV4Tw,30705
16
+ etlplus/api/enums.py,sha256=Tvkru6V8fzQh2JM2FDLcA_yaPENOKz5JgzxLhieqEvc,1141
21
17
  etlplus/api/errors.py,sha256=XjI2xW-sypMUNUbqfc2S57-IGyWnH3oCDFhCmKYYI_Q,4648
22
- etlplus/api/request_manager.py,sha256=YkDz803HM3BBzamsEZdSdE9fbVT0avMbTaLAgar9Wzo,18481
18
+ etlplus/api/request_manager.py,sha256=fhzPV5x7DqpKqoLvfDR8GKhBX_QBMtvZsRXxVnQQElY,18674
23
19
  etlplus/api/retry_manager.py,sha256=0GDhJVyIlb1Ww35JUWlYoa8QYUPjKLBtxQeZj3TdLbY,11306
24
- etlplus/api/transport.py,sha256=LRsQEPxIYrvXQQMvgPPkIl_57YCmanzsWNEnSYdP_d8,9164
25
- etlplus/api/types.py,sha256=687JigIf3qfYxgGTNBaMNsQsrza5Pja6DcK5llM9oRU,4591
20
+ etlplus/api/transport.py,sha256=DVWzWFZLfQQXaTJ60w-SzdXRxiOE8llPprpUB5CtSyg,9410
21
+ etlplus/api/types.py,sha256=ijHgREN5akEFF3th2yNdWbhJhXvAxh_24qQgg_sMB4w,4653
22
+ etlplus/api/utils.py,sha256=U39OXcrPiLD9m0Y03pACXIIOyuuDPO6RRKuTcwEayBE,26249
26
23
  etlplus/api/pagination/__init__.py,sha256=a4UX2J0AG8RMvmHt_CCofUm5vSmFo6GAfkb8XnSXypM,1395
27
- etlplus/api/pagination/client.py,sha256=42cG442od3mQkw_JsvGvxT_w7y9J4HPM5PB4tFFU6EQ,5383
24
+ etlplus/api/pagination/client.py,sha256=yMEpWqRxTCD4zRc9OYtEyUtShpGH5atiHFEAt95v2FE,5394
28
25
  etlplus/api/pagination/config.py,sha256=3dXDJ-nMbO9Zk6i344n4roBFbUlHsa294D1_plPmm6E,13579
29
26
  etlplus/api/pagination/paginator.py,sha256=wtdY_er4yfjx5yTUQJ1gPq-IuWmpLAHeG5buBQZJm54,24453
30
27
  etlplus/api/rate_limiting/__init__.py,sha256=ZySB1dZettEDnWvI1EHf_TZ9L08M_kKsNR-Y_lbU6kI,1070
31
- etlplus/api/rate_limiting/config.py,sha256=2b4wIynblN-1EyMqI4aXa71SljzSjXYh5N1Nngr3jOg,9406
32
- etlplus/api/rate_limiting/rate_limiter.py,sha256=Uxozqd_Ej5Lsj-M-mLT2WexChgWh7x35_YP10yqYPQA,7159
33
- etlplus/cli/README.md,sha256=rl9VYNH5MluV0rh-eP7TbxJZ5BTMEIaksxhl_JXpYio,1233
28
+ etlplus/api/rate_limiting/config.py,sha256=eB-dSOG-c5awYeEpnDsQJ5pO8BJtEpGYxOunBetWiB0,9775
29
+ etlplus/api/rate_limiting/rate_limiter.py,sha256=heAasm1KLeBFmoJKPz6W-eQbNuahMgG1E9-z8zGEUro,7035
30
+ etlplus/cli/README.md,sha256=8H_G2d3HteYIU6ReX9K9DM485QjWDT5vHMQbGD_vv20,1237
34
31
  etlplus/cli/__init__.py,sha256=J97-Rv931IL1_b4AXnB7Fbbd7HKnHBpx18NQfC_kE6c,299
35
32
  etlplus/cli/commands.py,sha256=g8_m3A8HEMyTRu2HctNiRoi2gtB5oSZCUEcyq-PIXos,24669
36
33
  etlplus/cli/constants.py,sha256=E6Uy4WauLa_0zkzxqImXh-bb1gKdb9sBZQVc8QOzr2Q,1943
37
- etlplus/cli/handlers.py,sha256=FvnYWKRg4u7iCcIvAJtpjDEbqw2DHj3G34NXJbMwnHk,17754
34
+ etlplus/cli/handlers.py,sha256=mILI386pf2RzfI7WJfXJ13huIGwsqFfcYx4sNIf1aWU,18174
38
35
  etlplus/cli/io.py,sha256=EFaBPYaBOyOllfMQWXgTjy-MPiGfNejicpD7ROrPyAE,7840
39
36
  etlplus/cli/main.py,sha256=IgeqxypixfwLHR-QcpgVMQ7vMZ865bXOh2oO9v-BWeM,5234
40
37
  etlplus/cli/options.py,sha256=vfXT3YLh7wG1iC-aTdSg6ItMC8l6n0Lozmy53XjqLbA,1199
41
38
  etlplus/cli/state.py,sha256=Pfd8ru0wYIN7eGp1_A0tioqs1LiCDZCuJ6AnjZb6yYQ,8027
42
39
  etlplus/cli/types.py,sha256=tclhKVJXDqHzlTQBYKARfqMgDOcuBJ-Zej2pvFy96WM,652
43
- etlplus/config/README.md,sha256=ot6oFZxTz4x83mj1_FrQ13dO0z2QkRFDnkCkx7NPsSs,1636
44
- etlplus/config/__init__.py,sha256=VZWzOg7d2YR9NT6UwKTv44yf2FRUMjTHynkm1Dl5Qzo,1486
45
- etlplus/config/connector.py,sha256=0-TIwevHbKRHVmucvyGpPd-3tB1dKHB-dj0yJ6kq5eY,9809
46
- etlplus/config/jobs.py,sha256=hmzRCqt0OvCEZZR4ONKrd3lvSv0OmayjLc4yOBk3ug8,7399
47
- etlplus/config/pipeline.py,sha256=m4Jh0ctFcKrIx6zR7LEC0sYY5wq0o8NqOruWPlz6qmA,9494
48
- etlplus/config/profile.py,sha256=Ss2zedQGjkaGSpvBLTD4SZaWViMJ7TJPLB8Q2_BTpPg,1898
49
- etlplus/config/types.py,sha256=a0epJ3z16HQ5bY3Ctf8s_cQPa3f0HHcwdOcjCP2xoG4,4954
50
- etlplus/config/utils.py,sha256=4SUHMkt5bKBhMhiJm-DrnmE2Q4TfOgdNCKz8PJDS27o,3443
51
- etlplus/database/README.md,sha256=nUQVwLwGzmpA5_u4oYJYkPIhIuJAIdWsoeRgr4joAIE,1431
40
+ etlplus/config/README.md,sha256=CBeUW6IBfS8_U1iW4LzMQiAshcaTr2hgMDW3bos3BUY,1467
41
+ etlplus/config/__init__.py,sha256=rjUC-OUH_dXqG11B5r0hlJuss1J_nSinkvoygfuqId8,921
42
+ etlplus/config/types.py,sha256=3EyibjzqjK3GQu0fsvbmkfHERDtubEmtOU_lXsgXQuQ,3603
43
+ etlplus/database/README.md,sha256=3Af5BEGLkBmMoGOLtS1GQuj4wKPh_CwSp5NEPMf2uaY,1435
52
44
  etlplus/database/__init__.py,sha256=AKJsDl2RHuRGPS-eXgNJeh4aSncJP5Y0yLApBF6i7i8,1052
53
45
  etlplus/database/ddl.py,sha256=0dEM9SJMMabkhI_h-Fc0j9a1Sl5lSyZdI0bIeBVGm10,7913
54
46
  etlplus/database/engine.py,sha256=PUxXLvLPyc-KaxuW7fXe12wYci7EvUp-Ad1H3bGhUog,4058
55
47
  etlplus/database/orm.py,sha256=gCSqH-CjQz6tV9133-VqgiwokK5ylun0BwXaIWfImAo,10008
56
48
  etlplus/database/schema.py,sha256=813C0Dd3WE53KTYot4dgjAxctgKXLXx-8_Rk_4r2e28,7022
57
49
  etlplus/database/types.py,sha256=_pkQyC14TzAlgyeIqZG4F5LWYknZbHw3TW68Auk7Ya0,795
58
- etlplus/file/README.md,sha256=avWnyeKfs3uP3qa-DVBJ6t05jS2oFUPeQ3xf1Ph0eC0,3626
50
+ etlplus/file/README.md,sha256=ivU8svVs1fktQiW5ozvh1N-IOSLCAQ3oM9bW8DUFwIw,3630
59
51
  etlplus/file/__init__.py,sha256=X03bosSM-uSd6dh3ur0un6_ozFRw2Tm4PE6kVUjtXK8,475
60
52
  etlplus/file/_imports.py,sha256=9e8CWjyNIRcmiULEPuwtnJELUOXd4EvVv_vDnDYiB9c,3121
61
53
  etlplus/file/_io.py,sha256=GXTcvjfXQX4rSdyu1JNhFmqQJlirDqd8dEGCN3dHvNg,2968
@@ -71,7 +63,7 @@ etlplus/file/csv.py,sha256=6zXt7OKXm_6k8MrDyw8DdEwpQQrmrxG6myrDplF87_E,1744
71
63
  etlplus/file/dat.py,sha256=j-GpY49SmkZtDUzZK6CbrHY9k6N83pyGcMqVGgJZ9cs,1642
72
64
  etlplus/file/dta.py,sha256=cEprcahuYEncDYEBZiEoHyg-1jgBsr9eCHPLdI-naXM,1616
73
65
  etlplus/file/duckdb.py,sha256=hQ8PWcvYILpkgPEtWeqbT_0yhQpJN9bJh1OwQQCcRD4,1631
74
- etlplus/file/enums.py,sha256=O40_cHazyvLFTK1hSErK0a8EMYQy4TJPX4El7cXO3pc,11083
66
+ etlplus/file/enums.py,sha256=d3VGF1IbI2Vye3A9WLeMyo5dqlo2Q1TrUp9GaG7a62g,11067
75
67
  etlplus/file/feather.py,sha256=U19T5V_08ooK1STclE9nDvsnUFzu7nvQvi6J09iC-_0,2669
76
68
  etlplus/file/fwf.py,sha256=WLbvL94cyLCOYfhABJvoIQc1fljtz3yOuA7X4Fc4QGo,1589
77
69
  etlplus/file/gz.py,sha256=NKsvIV7TIWn8USbvuZmRH9hr6OrXh4TzTfDykHD41Kk,2631
@@ -118,16 +110,30 @@ etlplus/file/xpt.py,sha256=JLqOkZ60awNsPXSqLKcPUwqZLPhPR05zk4EVRdEfvoU,1702
118
110
  etlplus/file/yaml.py,sha256=8BEqCELaTQ_nRu1iksLBHVj19P6JmcUf5__fe0yVigw,2449
119
111
  etlplus/file/zip.py,sha256=nd26V3S0edklriKnKOGDTLlO8RBXTda_zLLEQrJgKL4,4185
120
112
  etlplus/file/zsav.py,sha256=2WxjXamvzj0adDbWGMWM3-cj_LsCRjyZz4J907lNkPk,1664
121
- etlplus/templates/README.md,sha256=kHSZ8FWcrlrcWz0hBIbho-k1Bi-PL-DQ7g02o-g70c8,1355
113
+ etlplus/ops/README.md,sha256=8omi7DYZhelc26JKk8Cm8QR8I3OGwziysPj1ivx41iQ,1380
114
+ etlplus/ops/__init__.py,sha256=NIIr2f-AZj5B0piBt6gjv46Yn0SzGYxEe6BPoopRh38,1702
115
+ etlplus/ops/extract.py,sha256=OJozX25qTjME7m9aTdVPJScT3GHHgopGM8uHo_rHm1Y,5783
116
+ etlplus/ops/load.py,sha256=RgEKnVygRN2cPDpzihU8UsIhd4eVoj0cPe0jBuNC0u4,8328
117
+ etlplus/ops/run.py,sha256=JOPQxrciRUQ67FJhUcZ-pW1aiYGZUdxHLwhzWLNCaDo,13528
118
+ etlplus/ops/transform.py,sha256=1P43WYUaw872JDU86FhbbbkP8xnBWpgEPn2Q-z4ywls,25421
119
+ etlplus/ops/utils.py,sha256=tbV-s3NjIGO-GfdyJFxPYIYihPibNo-4TbdRq9vWVWs,11480
120
+ etlplus/ops/validate.py,sha256=gLa5zcwhxGbaIhH-OqTwDsQAgAYZSajLVGwwyeT2OZk,13257
121
+ etlplus/templates/README.md,sha256=IfPXlj1TGVA-uFWosHJhE2rabFW-znxOlOMazO9Z5cE,1361
122
122
  etlplus/templates/__init__.py,sha256=tsniN7XJYs3NwYxJ6c2HD5upHP3CDkLx-bQCMt97UOM,106
123
123
  etlplus/templates/ddl.sql.j2,sha256=s8fMWvcb4eaJVXkifuib1aQPljtZ8buuyB_uA-ZdU3Q,4734
124
124
  etlplus/templates/view.sql.j2,sha256=Iy8DHfhq5yyvrUKDxqp_aHIEXY4Tm6j4wT7YDEFWAhk,2180
125
- etlplus/validation/README.md,sha256=qusyiyJu2DsaK80jlwfXVZ0iDgeuTPOX2EL3a_fcFiw,1401
126
- etlplus/validation/__init__.py,sha256=Pe5Xg1_EA4uiNZGYu5WTF3j7odjmyxnAJ8rcioaplSQ,1254
127
- etlplus/validation/utils.py,sha256=Mtqg449VIke0ziy_wd2r6yrwJzQkA1iulZC87FzXMjo,10201
128
- etlplus-0.12.12.dist-info/licenses/LICENSE,sha256=MuNO63i6kWmgnV2pbP2SLqP54mk1BGmu7CmbtxMmT-U,1069
129
- etlplus-0.12.12.dist-info/METADATA,sha256=GsFkraquAsxEY-ldW-heU_9WKIMHXKANlc9FsKTRoN8,26886
130
- etlplus-0.12.12.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
131
- etlplus-0.12.12.dist-info/entry_points.txt,sha256=6w-2-jzuPa55spzK34h-UKh2JTEShh38adFRONNP9QE,45
132
- etlplus-0.12.12.dist-info/top_level.txt,sha256=aWWF-udn_sLGuHTM6W6MLh99ArS9ROkUWO8Mi8y1_2U,8
133
- etlplus-0.12.12.dist-info/RECORD,,
125
+ etlplus/workflow/README.md,sha256=D1oloiJCOHiqpqgv3m3qpRSIUOMIQcWtIsOPv7KkNI0,1652
126
+ etlplus/workflow/__init__.py,sha256=LxI9VGlDBUc9ADoK8JNn3oVsGeaz1Uhjonn4Y5KIJdM,967
127
+ etlplus/workflow/connector.py,sha256=9b4KF2uNKaJtsQadwT7Id8OujfJM8GLJHqI-n4kFsGA,9851
128
+ etlplus/workflow/dag.py,sha256=kp31dORgk0GHbct_bipU5hu_0elwBtwLsXGjMWuhFHI,2503
129
+ etlplus/workflow/jobs.py,sha256=yFNj4S7ORMtpYSA0nCAUgb4E5msW7dyvtQVPBb-CAK8,7938
130
+ etlplus/workflow/pipeline.py,sha256=DL6XsX47gGPiURH8Qj1Ixm0RctI3taqo3e6Asg8fpto,9624
131
+ etlplus/workflow/profile.py,sha256=dZ6P50k_ZqXnrbgrbODUqgVkymbchcEqfZR-ExjTd3M,1935
132
+ etlplus/workflow/types.py,sha256=kVdOMT8qwnWlD7C4qWv-uF7r6-Kk-RlMZmoY8tnIo7A,2769
133
+ etlplus/workflow/utils.py,sha256=4SUHMkt5bKBhMhiJm-DrnmE2Q4TfOgdNCKz8PJDS27o,3443
134
+ etlplus-0.15.0.dist-info/licenses/LICENSE,sha256=MuNO63i6kWmgnV2pbP2SLqP54mk1BGmu7CmbtxMmT-U,1069
135
+ etlplus-0.15.0.dist-info/METADATA,sha256=YdRPU6L9SNAYpfB6fypG3-KewetI_QoyDlE2WnS2wPQ,28115
136
+ etlplus-0.15.0.dist-info/WHEEL,sha256=qELbo2s1Yzl39ZmrAibXA2jjPLUYfnVhUNTlyF1rq0Y,92
137
+ etlplus-0.15.0.dist-info/entry_points.txt,sha256=6w-2-jzuPa55spzK34h-UKh2JTEShh38adFRONNP9QE,45
138
+ etlplus-0.15.0.dist-info/top_level.txt,sha256=aWWF-udn_sLGuHTM6W6MLh99ArS9ROkUWO8Mi8y1_2U,8
139
+ etlplus-0.15.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.9.0)
2
+ Generator: setuptools (80.10.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,44 +0,0 @@
1
- """
2
- :mod:`etlplus.validation` package.
3
-
4
- Conditional validation utilities used across the ETL pipeline.
5
-
6
- The package intentionally exposes a single helper, :func:`maybe_validate`, to
7
- keep the public API compact and predictable. Supporting logic lives in
8
- ``etlplus.validation.utils`` where validation configuration is normalized,
9
- reducing the likelihood of phase/option mismatches.
10
-
11
- Examples
12
- --------
13
- >>> from etlplus.validation import maybe_validate
14
- >>> payload = {'name': 'Alice'}
15
- >>> rules = {'required': ['name']}
16
- >>> def validator(data, config):
17
- ... missing = [field for field in config['required'] if field not in data]
18
- ... return {'valid': not missing, 'errors': missing, 'data': data}
19
- >>> maybe_validate(
20
- ... payload,
21
- ... when='both',
22
- ... enabled=True,
23
- ... rules=rules,
24
- ... phase='before_transform',
25
- ... severity='warn',
26
- ... validate_fn=validator,
27
- ... print_json_fn=lambda message: message,
28
- ... )
29
- {'name': 'Alice'}
30
-
31
- See Also
32
- --------
33
- - :mod:`etlplus.validation.utils` for implementation details and helper
34
- utilities.
35
- """
36
-
37
- from __future__ import annotations
38
-
39
- from .utils import maybe_validate
40
-
41
- # SECTION: EXPORTS ========================================================== #
42
-
43
-
44
- __all__ = ['maybe_validate']
File without changes