etlplus 0.9.0__py3-none-any.whl → 0.9.2__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 (120) hide show
  1. etlplus/README.md +37 -0
  2. etlplus/__init__.py +1 -26
  3. etlplus/api/README.md +51 -3
  4. etlplus/api/__init__.py +10 -0
  5. etlplus/api/config.py +39 -28
  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 +96 -6
  14. etlplus/{run_helpers.py → api/utils.py} +209 -153
  15. etlplus/cli/README.md +40 -0
  16. etlplus/cli/commands.py +94 -61
  17. etlplus/cli/constants.py +1 -1
  18. etlplus/cli/handlers.py +40 -12
  19. etlplus/cli/io.py +2 -2
  20. etlplus/cli/main.py +1 -1
  21. etlplus/cli/state.py +4 -7
  22. etlplus/database/README.md +48 -0
  23. etlplus/database/ddl.py +1 -1
  24. etlplus/database/engine.py +19 -3
  25. etlplus/database/orm.py +2 -0
  26. etlplus/database/schema.py +1 -1
  27. etlplus/enums.py +1 -107
  28. etlplus/file/README.md +105 -0
  29. etlplus/file/__init__.py +25 -0
  30. etlplus/file/_imports.py +141 -0
  31. etlplus/file/_io.py +160 -0
  32. etlplus/file/accdb.py +78 -0
  33. etlplus/file/arrow.py +78 -0
  34. etlplus/file/avro.py +176 -0
  35. etlplus/file/bson.py +77 -0
  36. etlplus/file/cbor.py +78 -0
  37. etlplus/file/cfg.py +79 -0
  38. etlplus/file/conf.py +80 -0
  39. etlplus/file/core.py +322 -0
  40. etlplus/file/csv.py +79 -0
  41. etlplus/file/dat.py +78 -0
  42. etlplus/file/dta.py +77 -0
  43. etlplus/file/duckdb.py +78 -0
  44. etlplus/file/enums.py +343 -0
  45. etlplus/file/feather.py +111 -0
  46. etlplus/file/fwf.py +77 -0
  47. etlplus/file/gz.py +123 -0
  48. etlplus/file/hbs.py +78 -0
  49. etlplus/file/hdf5.py +78 -0
  50. etlplus/file/ini.py +79 -0
  51. etlplus/file/ion.py +78 -0
  52. etlplus/file/jinja2.py +78 -0
  53. etlplus/file/json.py +98 -0
  54. etlplus/file/log.py +78 -0
  55. etlplus/file/mat.py +78 -0
  56. etlplus/file/mdb.py +78 -0
  57. etlplus/file/msgpack.py +78 -0
  58. etlplus/file/mustache.py +78 -0
  59. etlplus/file/nc.py +78 -0
  60. etlplus/file/ndjson.py +108 -0
  61. etlplus/file/numbers.py +75 -0
  62. etlplus/file/ods.py +79 -0
  63. etlplus/file/orc.py +111 -0
  64. etlplus/file/parquet.py +113 -0
  65. etlplus/file/pb.py +78 -0
  66. etlplus/file/pbf.py +77 -0
  67. etlplus/file/properties.py +78 -0
  68. etlplus/file/proto.py +77 -0
  69. etlplus/file/psv.py +79 -0
  70. etlplus/file/rda.py +78 -0
  71. etlplus/file/rds.py +78 -0
  72. etlplus/file/sas7bdat.py +78 -0
  73. etlplus/file/sav.py +77 -0
  74. etlplus/file/sqlite.py +78 -0
  75. etlplus/file/stub.py +84 -0
  76. etlplus/file/sylk.py +77 -0
  77. etlplus/file/tab.py +81 -0
  78. etlplus/file/toml.py +78 -0
  79. etlplus/file/tsv.py +80 -0
  80. etlplus/file/txt.py +102 -0
  81. etlplus/file/vm.py +78 -0
  82. etlplus/file/wks.py +77 -0
  83. etlplus/file/xls.py +88 -0
  84. etlplus/file/xlsm.py +79 -0
  85. etlplus/file/xlsx.py +99 -0
  86. etlplus/file/xml.py +185 -0
  87. etlplus/file/xpt.py +78 -0
  88. etlplus/file/yaml.py +95 -0
  89. etlplus/file/zip.py +175 -0
  90. etlplus/file/zsav.py +77 -0
  91. etlplus/ops/README.md +50 -0
  92. etlplus/ops/__init__.py +61 -0
  93. etlplus/{extract.py → ops/extract.py} +81 -99
  94. etlplus/{load.py → ops/load.py} +78 -101
  95. etlplus/{run.py → ops/run.py} +159 -127
  96. etlplus/{transform.py → ops/transform.py} +75 -68
  97. etlplus/{validation → ops}/utils.py +53 -17
  98. etlplus/{validate.py → ops/validate.py} +22 -12
  99. etlplus/templates/README.md +46 -0
  100. etlplus/types.py +5 -4
  101. etlplus/utils.py +136 -2
  102. etlplus/workflow/README.md +52 -0
  103. etlplus/{config → workflow}/__init__.py +10 -23
  104. etlplus/{config → workflow}/connector.py +58 -44
  105. etlplus/workflow/dag.py +105 -0
  106. etlplus/{config → workflow}/jobs.py +105 -32
  107. etlplus/{config → workflow}/pipeline.py +59 -51
  108. etlplus/{config → workflow}/profile.py +8 -5
  109. etlplus/workflow/types.py +115 -0
  110. {etlplus-0.9.0.dist-info → etlplus-0.9.2.dist-info}/METADATA +210 -17
  111. etlplus-0.9.2.dist-info/RECORD +134 -0
  112. {etlplus-0.9.0.dist-info → etlplus-0.9.2.dist-info}/WHEEL +1 -1
  113. etlplus/config/types.py +0 -204
  114. etlplus/config/utils.py +0 -120
  115. etlplus/file.py +0 -657
  116. etlplus/validation/__init__.py +0 -44
  117. etlplus-0.9.0.dist-info/RECORD +0 -65
  118. {etlplus-0.9.0.dist-info → etlplus-0.9.2.dist-info}/entry_points.txt +0 -0
  119. {etlplus-0.9.0.dist-info → etlplus-0.9.2.dist-info}/licenses/LICENSE +0 -0
  120. {etlplus-0.9.0.dist-info → etlplus-0.9.2.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.workflow`.
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.9.0
3
+ Version: 0.9.2
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
@@ -17,8 +17,11 @@ Classifier: Programming Language :: Python :: 3.14
17
17
  Requires-Python: >=3.13,<3.15
18
18
  Description-Content-Type: text/markdown
19
19
  License-File: LICENSE
20
+ Requires-Dist: fastavro>=1.12.1
20
21
  Requires-Dist: jinja2>=3.1.6
22
+ Requires-Dist: openpyxl>=3.1.5
21
23
  Requires-Dist: pyodbc>=5.3.0
24
+ Requires-Dist: pyarrow>=22.0.0
22
25
  Requires-Dist: python-dotenv>=1.2.1
23
26
  Requires-Dist: pandas>=2.3.3
24
27
  Requires-Dist: pydantic>=2.12.5
@@ -26,6 +29,8 @@ Requires-Dist: PyYAML>=6.0.3
26
29
  Requires-Dist: requests>=2.32.5
27
30
  Requires-Dist: SQLAlchemy>=2.0.45
28
31
  Requires-Dist: typer>=0.21.0
32
+ Requires-Dist: xlrd>=2.0.2
33
+ Requires-Dist: xlwt>=1.3.0
29
34
  Provides-Extra: dev
30
35
  Requires-Dist: black>=25.9.0; extra == "dev"
31
36
  Requires-Dist: build>=1.2.2; extra == "dev"
@@ -59,9 +64,25 @@ ETLPlus is a veritable Swiss Army knife for enabling simple ETL operations, offe
59
64
  package and command-line interface for data extraction, validation, transformation, and loading.
60
65
 
61
66
  - [ETLPlus](#etlplus)
67
+ - [Getting Started](#getting-started)
62
68
  - [Features](#features)
63
69
  - [Installation](#installation)
64
70
  - [Quickstart](#quickstart)
71
+ - [Data Connectors](#data-connectors)
72
+ - [REST APIs (`api`)](#rest-apis-api)
73
+ - [Databases (`database`)](#databases-database)
74
+ - [Files (`file`)](#files-file)
75
+ - [Stubbed / Placeholder](#stubbed--placeholder)
76
+ - [Tabular \& Delimited Text](#tabular--delimited-text)
77
+ - [Semi-Structured Text](#semi-structured-text)
78
+ - [Columnar / Analytics-Friendly](#columnar--analytics-friendly)
79
+ - [Binary Serialization and Interchange](#binary-serialization-and-interchange)
80
+ - [Databases and Embedded Storage](#databases-and-embedded-storage)
81
+ - [Spreadsheets](#spreadsheets)
82
+ - [Statistical / Scientific / Numeric Computing](#statistical--scientific--numeric-computing)
83
+ - [Logs and Event Streams](#logs-and-event-streams)
84
+ - [Data Archives](#data-archives)
85
+ - [Templates](#templates)
65
86
  - [Usage](#usage)
66
87
  - [Command Line Interface](#command-line-interface)
67
88
  - [Argument Order and Required Options](#argument-order-and-required-options)
@@ -87,11 +108,27 @@ package and command-line interface for data extraction, validation, transformati
87
108
  - [Linting](#linting)
88
109
  - [Updating Demo Snippets](#updating-demo-snippets)
89
110
  - [Releasing to PyPI](#releasing-to-pypi)
90
- - [Links](#links)
91
111
  - [License](#license)
92
112
  - [Contributing](#contributing)
113
+ - [Documentation](#documentation)
114
+ - [Python Packages/Subpackage](#python-packagessubpackage)
115
+ - [Community Health](#community-health)
116
+ - [Other](#other)
93
117
  - [Acknowledgments](#acknowledgments)
94
118
 
119
+ ## Getting Started
120
+
121
+ ETLPlus helps you extract, validate, transform, and load data from files, databases, and APIs, either
122
+ as a Python library or from the command line.
123
+
124
+ To get started:
125
+
126
+ - See [Installation](#installation) for setup instructions.
127
+ - Try the [Quickstart](#quickstart) for a minimal working example (CLI and Python).
128
+ - Explore [Usage](#usage) for more detailed options and workflows.
129
+
130
+ ETLPlus supports Python 3.13 and above.
131
+
95
132
  ## Features
96
133
 
97
134
  - **Check** data pipeline definitions before running them:
@@ -159,7 +196,7 @@ etlplus extract file examples/data/sample.csv \
159
196
  [Python API](#python-api):
160
197
 
161
198
  ```python
162
- from etlplus import extract, transform, validate, load
199
+ from etlplus.ops import extract, transform, validate, load
163
200
 
164
201
  data = extract("file", "input.csv")
165
202
  ops = {"filter": {"field": "age", "op": "gt", "value": 25}, "select": ["name", "email"]}
@@ -169,6 +206,140 @@ assert validate(filtered, rules)["valid"]
169
206
  load(filtered, "file", "temp/sample_output.json", file_format="json")
170
207
  ```
171
208
 
209
+ ## Data Connectors
210
+
211
+ Data connectors abstract sources from which to extract data and targets to which to load data. They
212
+ are differentiated by their types, each of which is represented in the subsections below.
213
+
214
+ ### REST APIs (`api`)
215
+
216
+ ETLPlus can extract from REST APIs and load results via common HTTP methods. Supported operations
217
+ include GET for extract and PATCH/POST/PUT for load.
218
+
219
+ ### Databases (`database`)
220
+
221
+ Database connectors use connection strings for extraction and loading, and
222
+ DDL can be rendered from table specs for migrations or schema checks.
223
+
224
+ ### Files (`file`)
225
+
226
+ Recognized file formats are listed in the tables below. Support for reading to or writing from a recognized file format is marked as:
227
+
228
+ - **Y**: implemented (may require optional dependencies)
229
+ - **N**: stubbed or not yet implemented
230
+
231
+ #### Stubbed / Placeholder
232
+
233
+ | Format | Read | Write | Description |
234
+ | --- | --- | --- | --- |
235
+ | `stub` | N | Placeholder format for tests and future connectors. |
236
+
237
+ #### Tabular & Delimited Text
238
+
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 |
248
+
249
+ #### Semi-Structured Text
250
+
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 |
262
+
263
+ #### Columnar / Analytics-Friendly
264
+
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 |
271
+
272
+ #### Binary Serialization and Interchange
273
+
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 |
284
+
285
+ #### Databases and Embedded Storage
286
+
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 |
293
+
294
+ #### Spreadsheets
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
+
323
+ | Format | Supported | Description |
324
+ | --- | --- | --- |
325
+ | `log` | N | N | Generic log file |
326
+
327
+ #### Data Archives
328
+
329
+ | Format | Read | Write | Description |
330
+ | --- | --- | --- | --- |
331
+ | `gz` | Y | Y | Gzip-compressed file |
332
+ | `zip` | Y | Y | ZIP archive |
333
+
334
+ #### Templates
335
+
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 |
342
+
172
343
  ## Usage
173
344
 
174
345
  ### Command Line Interface
@@ -360,7 +531,7 @@ cat examples/data/sample.json \
360
531
  Use ETLPlus as a Python library:
361
532
 
362
533
  ```python
363
- from etlplus import extract, validate, transform, load
534
+ from etlplus.ops import extract, validate, transform, load
364
535
 
365
536
  # Extract data
366
537
  data = extract("file", "data.json")
@@ -416,7 +587,7 @@ etlplus transform \
416
587
  # 3. Validate transformed data
417
588
  etlplus validate \
418
589
  --rules '{"name": {"type": "string", "required": true}, "email": {"type": "string", "required": true}}' \
419
- temo/sample_transformed.json
590
+ temp/sample_transformed.json
420
591
 
421
592
  # 4. Load to CSV
422
593
  cat temp/sample_transformed.json \
@@ -555,7 +726,7 @@ We split tests into two layers:
555
726
  pagination + rate limit defaults, file/API connector interactions) may touch temp files and use
556
727
  fake clients.
557
728
 
558
- 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
559
730
  criteria: [`CONTRIBUTING.md#testing`](CONTRIBUTING.md#testing).
560
731
 
561
732
  ### Code Coverage
@@ -603,17 +774,6 @@ git push origin v1.4.0
603
774
  If you want an extra smoke-test before tagging, run `make dist && pip install dist/*.whl` locally;
604
775
  this exercises the same build path the workflow uses.
605
776
 
606
- ## Links
607
-
608
- - API client docs: [`etlplus/api/README.md`](etlplus/api/README.md)
609
- - Examples: [`examples/README.md`](examples/README.md)
610
- - Pipeline authoring guide: [`docs/pipeline-guide.md`](docs/pipeline-guide.md)
611
- - Runner internals: [`docs/run-module.md`](docs/run-module.md)
612
- - Design notes (Mapping inputs, dict outputs): [`docs/pipeline-guide.md#design-notes-mapping-inputs-dict-outputs`](docs/pipeline-guide.md#design-notes-mapping-inputs-dict-outputs)
613
- - Typing philosophy: [`CONTRIBUTING.md#typing-philosophy`](CONTRIBUTING.md#typing-philosophy)
614
- - Demo and walkthrough: [`DEMO.md`](DEMO.md)
615
- - Additional references: [`REFERENCES.md`](`REFERENCES.md)
616
-
617
777
  ## License
618
778
 
619
779
  This project is licensed under the [MIT License](LICENSE).
@@ -637,6 +797,39 @@ If you choose to be a code contributor, please first refer these documents:
637
797
  - Typing philosophy (TypedDicts as editor hints, permissive runtime):
638
798
  [`CONTRIBUTING.md#typing-philosophy`](CONTRIBUTING.md#typing-philosophy)
639
799
 
800
+ ## Documentation
801
+
802
+ ### Python Packages/Subpackage
803
+
804
+ Navigate to detailed documentation for each subpackage:
805
+
806
+ - [etlplus.api](etlplus/api/README.md): Lightweight HTTP client and paginated REST helpers
807
+ - [etlplus.file](etlplus/file/README.md): Unified file format support and helpers
808
+ - [etlplus.cli](etlplus/cli/README.md): Command-line interface definitions for `etlplus`
809
+ - [etlplus.database](etlplus/database/README.md): Database engine, schema, and ORM helpers
810
+ - [etlplus.templates](etlplus/templates/README.md): SQL and DDL template helpers
811
+ - [etlplus.validation](etlplus/validation/README.md): Data validation utilities and helpers
812
+ - [etlplus.workflow](etlplus/workflow/README.md): Helpers for data connectors, pipelines, jobs, and
813
+ profiles
814
+
815
+ ### Community Health
816
+
817
+ - [Contributing Guidelines](CONTRIBUTING.md): How to contribute, report issues, and submit PRs
818
+ - [Code of Conduct](CODE_OF_CONDUCT.md): Community standards and expectations
819
+ - [Security Policy](SECURITY.md): Responsible disclosure and vulnerability reporting
820
+ - [Support](SUPPORT.md): Where to get help
821
+
822
+ ### Other
823
+
824
+ - API client docs: [`etlplus/api/README.md`](etlplus/api/README.md)
825
+ - Examples: [`examples/README.md`](examples/README.md)
826
+ - Pipeline authoring guide: [`docs/pipeline-guide.md`](docs/pipeline-guide.md)
827
+ - Runner internals: [`docs/run-module.md`](docs/run-module.md)
828
+ - Design notes (Mapping inputs, dict outputs): [`docs/pipeline-guide.md#design-notes-mapping-inputs-dict-outputs`](docs/pipeline-guide.md#design-notes-mapping-inputs-dict-outputs)
829
+ - Typing philosophy: [`CONTRIBUTING.md#typing-philosophy`](CONTRIBUTING.md#typing-philosophy)
830
+ - Demo and walkthrough: [`DEMO.md`](DEMO.md)
831
+ - Additional references: [`REFERENCES.md`](REFERENCES.md)
832
+
640
833
  ## Acknowledgments
641
834
 
642
835
  ETLPlus is inspired by common work patterns in data engineering and software engineering patterns in
@@ -0,0 +1,134 @@
1
+ etlplus/README.md,sha256=JaMSomnMsHrTruDnonHqe83Rv4K0-e7Wy46tMeVoleU,1468
2
+ etlplus/__init__.py,sha256=mgTP4PJmRmsEjTCAizzzdtzAmhuHtarmPzphzdjvLgM,277
3
+ etlplus/__main__.py,sha256=btoROneNiigyfBU7BSzPKZ1R9gzBMpxcpsbPwmuHwTM,479
4
+ etlplus/__version__.py,sha256=1E0GMK_yUWCMQFKxXjTvyMwofi0qT2k4CDNiHWiymWE,327
5
+ etlplus/enums.py,sha256=ZxObavNilITJNT4Mf2hBy1s4kKtTFUTmrc8_whkxKNg,7541
6
+ etlplus/mixins.py,sha256=ifGpHwWv7U00yqGf-kN93vJax2IiK4jaGtTsPsO3Oak,1350
7
+ etlplus/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
+ etlplus/types.py,sha256=-knM5bWRq49k4o-KlW-GRsENcj2P-h6oPnEmuz3EJso,6214
9
+ etlplus/utils.py,sha256=JVOBPyjIv1C9EZWZuYdqCISS-Dpa-PHrFvvruu1R0HA,17171
10
+ etlplus/api/README.md,sha256=amxS_eIcsnNuVvD0x_w8nkyfedOTYbhlY0gGhaFg0DE,8705
11
+ etlplus/api/__init__.py,sha256=PK2lQv1FbsE7ZZS_ejevFZQSuOUHGApBc22YfHAzMqA,4615
12
+ etlplus/api/auth.py,sha256=GOO5on-LoMS1GXTAhtK9rFcfpjbBcNeA6NE5UZwIq0g,12158
13
+ etlplus/api/config.py,sha256=_8_iXpaHXQN6RQ1z0e3q0LTY936IYsc1SVcE6_sPT6E,17639
14
+ etlplus/api/endpoint_client.py,sha256=OPAvw3NkpSzeITqgRP1reyqX9Nc_XC8lAj6Yp7nV4Tw,30705
15
+ etlplus/api/enums.py,sha256=Tvkru6V8fzQh2JM2FDLcA_yaPENOKz5JgzxLhieqEvc,1141
16
+ etlplus/api/errors.py,sha256=XjI2xW-sypMUNUbqfc2S57-IGyWnH3oCDFhCmKYYI_Q,4648
17
+ etlplus/api/request_manager.py,sha256=fhzPV5x7DqpKqoLvfDR8GKhBX_QBMtvZsRXxVnQQElY,18674
18
+ etlplus/api/retry_manager.py,sha256=0GDhJVyIlb1Ww35JUWlYoa8QYUPjKLBtxQeZj3TdLbY,11306
19
+ etlplus/api/transport.py,sha256=DVWzWFZLfQQXaTJ60w-SzdXRxiOE8llPprpUB5CtSyg,9410
20
+ etlplus/api/types.py,sha256=geuKmnf6C2P9_tpRpOF90Uu7J160OL3RQpQ_CgJsSrM,6695
21
+ etlplus/api/utils.py,sha256=U39OXcrPiLD9m0Y03pACXIIOyuuDPO6RRKuTcwEayBE,26249
22
+ etlplus/api/pagination/__init__.py,sha256=a4UX2J0AG8RMvmHt_CCofUm5vSmFo6GAfkb8XnSXypM,1395
23
+ etlplus/api/pagination/client.py,sha256=yMEpWqRxTCD4zRc9OYtEyUtShpGH5atiHFEAt95v2FE,5394
24
+ etlplus/api/pagination/config.py,sha256=3dXDJ-nMbO9Zk6i344n4roBFbUlHsa294D1_plPmm6E,13579
25
+ etlplus/api/pagination/paginator.py,sha256=wtdY_er4yfjx5yTUQJ1gPq-IuWmpLAHeG5buBQZJm54,24453
26
+ etlplus/api/rate_limiting/__init__.py,sha256=ZySB1dZettEDnWvI1EHf_TZ9L08M_kKsNR-Y_lbU6kI,1070
27
+ etlplus/api/rate_limiting/config.py,sha256=eB-dSOG-c5awYeEpnDsQJ5pO8BJtEpGYxOunBetWiB0,9775
28
+ etlplus/api/rate_limiting/rate_limiter.py,sha256=heAasm1KLeBFmoJKPz6W-eQbNuahMgG1E9-z8zGEUro,7035
29
+ etlplus/cli/README.md,sha256=8H_G2d3HteYIU6ReX9K9DM485QjWDT5vHMQbGD_vv20,1237
30
+ etlplus/cli/__init__.py,sha256=J97-Rv931IL1_b4AXnB7Fbbd7HKnHBpx18NQfC_kE6c,299
31
+ etlplus/cli/commands.py,sha256=HFlg29tO6Jwv1NXWAHmvniLCyRSlboL55Arn9B8nZAM,25028
32
+ etlplus/cli/constants.py,sha256=E6Uy4WauLa_0zkzxqImXh-bb1gKdb9sBZQVc8QOzr2Q,1943
33
+ etlplus/cli/handlers.py,sha256=hXsgG3c6n8JDN4U3Svq6i2r21vetw5NcmXE1bGSwb9w,18560
34
+ etlplus/cli/io.py,sha256=EFaBPYaBOyOllfMQWXgTjy-MPiGfNejicpD7ROrPyAE,7840
35
+ etlplus/cli/main.py,sha256=d5yhCS6aNo_TKMvhdTS7qeJm4yb1S58gGBrUoBV7SCs,5241
36
+ etlplus/cli/options.py,sha256=vfXT3YLh7wG1iC-aTdSg6ItMC8l6n0Lozmy53XjqLbA,1199
37
+ etlplus/cli/state.py,sha256=3Dq5BKct0uAvRajtc2yHbsX7wqepZOwlAMKsyvQcnqk,7918
38
+ etlplus/cli/types.py,sha256=tclhKVJXDqHzlTQBYKARfqMgDOcuBJ-Zej2pvFy96WM,652
39
+ etlplus/database/README.md,sha256=3Af5BEGLkBmMoGOLtS1GQuj4wKPh_CwSp5NEPMf2uaY,1435
40
+ etlplus/database/__init__.py,sha256=AKJsDl2RHuRGPS-eXgNJeh4aSncJP5Y0yLApBF6i7i8,1052
41
+ etlplus/database/ddl.py,sha256=0dEM9SJMMabkhI_h-Fc0j9a1Sl5lSyZdI0bIeBVGm10,7913
42
+ etlplus/database/engine.py,sha256=gWgTjGoo1HYHrBuYX5l2P8avAR3XithzAiqUOpLHP-8,4386
43
+ etlplus/database/orm.py,sha256=ZCHkeVEUns2eievlFzmLyVKA3YVPea1xs6vrcUBZ7Jw,10010
44
+ etlplus/database/schema.py,sha256=813C0Dd3WE53KTYot4dgjAxctgKXLXx-8_Rk_4r2e28,7022
45
+ etlplus/database/types.py,sha256=_pkQyC14TzAlgyeIqZG4F5LWYknZbHw3TW68Auk7Ya0,795
46
+ etlplus/file/README.md,sha256=ivU8svVs1fktQiW5ozvh1N-IOSLCAQ3oM9bW8DUFwIw,3630
47
+ etlplus/file/__init__.py,sha256=X03bosSM-uSd6dh3ur0un6_ozFRw2Tm4PE6kVUjtXK8,475
48
+ etlplus/file/_imports.py,sha256=9e8CWjyNIRcmiULEPuwtnJELUOXd4EvVv_vDnDYiB9c,3121
49
+ etlplus/file/_io.py,sha256=2Dj7MH6r-yp_SsCe5GmuNN7Ta70qYzF_jKoMgnD3rME,3925
50
+ etlplus/file/accdb.py,sha256=xdBLrXHDonVJ1Z6-qZRrLBXpUwqw5nZYxDuxYMJHzVs,1681
51
+ etlplus/file/arrow.py,sha256=rYPqoCAI3cBHETYN3c0Xi7R5Nq7_prIdyESm3ll3Zos,1694
52
+ etlplus/file/avro.py,sha256=yFQMnWPcvC0CbDCyagoB9SHRIuvl2SXIoQJTBIlw4dA,4437
53
+ etlplus/file/bson.py,sha256=okCWQveCnaRxJ47Oy7-HpByEkiwmiSLSWc0a9eISuVg,1613
54
+ etlplus/file/cbor.py,sha256=hpXTqQ-ei4jYKt6-zq3frDXy-SWRpx1ThQUce6b01xU,1667
55
+ etlplus/file/cfg.py,sha256=cT2RKFgEMsAJaT9_EIPvYCzS4F9HdRJhEZTDMCVMZ4s,1710
56
+ etlplus/file/conf.py,sha256=TKkiuGf_r4pNlxKEgxn8d1Pza-4oeWZiYjvlpMk-un4,1768
57
+ etlplus/file/core.py,sha256=71AFsVwvAP6crsAphMkAmhqTwk_-TkEw9eByG6gwzpA,8862
58
+ etlplus/file/csv.py,sha256=6zXt7OKXm_6k8MrDyw8DdEwpQQrmrxG6myrDplF87_E,1744
59
+ etlplus/file/dat.py,sha256=j-GpY49SmkZtDUzZK6CbrHY9k6N83pyGcMqVGgJZ9cs,1642
60
+ etlplus/file/dta.py,sha256=cEprcahuYEncDYEBZiEoHyg-1jgBsr9eCHPLdI-naXM,1616
61
+ etlplus/file/duckdb.py,sha256=hQ8PWcvYILpkgPEtWeqbT_0yhQpJN9bJh1OwQQCcRD4,1631
62
+ etlplus/file/enums.py,sha256=d3VGF1IbI2Vye3A9WLeMyo5dqlo2Q1TrUp9GaG7a62g,11067
63
+ etlplus/file/feather.py,sha256=U19T5V_08ooK1STclE9nDvsnUFzu7nvQvi6J09iC-_0,2669
64
+ etlplus/file/fwf.py,sha256=WLbvL94cyLCOYfhABJvoIQc1fljtz3yOuA7X4Fc4QGo,1589
65
+ etlplus/file/gz.py,sha256=NKsvIV7TIWn8USbvuZmRH9hr6OrXh4TzTfDykHD41Kk,2631
66
+ etlplus/file/hbs.py,sha256=iz0tIVNmsCYjTLnE5x-m3Smh5QKbfuQA-sgOHOZ_T3g,1614
67
+ etlplus/file/hdf5.py,sha256=SZ-UbXTJGOYA82hdma7AFulWo9emH5Kih_RXC7f-Bfk,1624
68
+ etlplus/file/ini.py,sha256=HlvQyQC00oBD8KFBfznPjBx9wF1ZwXH7Yo1JaXqCq8I,1701
69
+ etlplus/file/ion.py,sha256=9q938jROTAcuUT5sRYvS1qIeoz9p8KkVWYDDS2-2A_4,1710
70
+ etlplus/file/jinja2.py,sha256=FFqGQjBnRgPQ-oJ3WqiKspJMj6g_J0fDKGwsoOJAEzk,1630
71
+ etlplus/file/json.py,sha256=m4eM8cPGHYAEppwLqBdq-t9gC2GtKPLptRTBeBfRimY,2130
72
+ etlplus/file/log.py,sha256=OmsGijXZn1VhN7BUklF8saoktxkmHh1MPLI_BbGDLyc,1681
73
+ etlplus/file/mat.py,sha256=u3jWMK8c4k9L0uVRiQSd7JgVQF-efoJj3QiKYtt1arA,1654
74
+ etlplus/file/mdb.py,sha256=hSCaxBbc_b9dGTBpR-Gb0UTY2r3zYUxoEiKuwpnx0kI,1657
75
+ etlplus/file/msgpack.py,sha256=9PTitVGnZM0yB2iiwsgLokai6DRmp2l2zfhyjEcajg8,1658
76
+ etlplus/file/mustache.py,sha256=F-xVUH69evPQkunUx746B4rnOHxgAUP6KVpexK3zI_Q,1647
77
+ etlplus/file/nc.py,sha256=3RFCl7OvCFAiwyVJJHF5_oa3UdGtDGsVU69OTMpiOdk,1670
78
+ etlplus/file/ndjson.py,sha256=fSMAAdyucGIVl6zVqylWSBosOg899wgIpIWCGm2HOWU,2432
79
+ etlplus/file/numbers.py,sha256=RSRC6sFYyWxmeTHWM7-D14MQQlDaz-FVehbSyG9u9Ds,1610
80
+ etlplus/file/ods.py,sha256=6XsWkcrBsvQxzMdeMulqwExl3BjRe8gR-kNu0-hiRPE,1800
81
+ etlplus/file/orc.py,sha256=fOO2jQwUr5FHbDve7ztmrE1Mb8uBMQtDo0yp-elVn8Q,2602
82
+ etlplus/file/parquet.py,sha256=nzMrUNQux7Of8Nn0c4d2WYuIJQwZY_xQiO_AuVMCzrI,2758
83
+ etlplus/file/pb.py,sha256=sg72vrjbp7azgEK_oRigmNdSqtEnsrBF24VjOohZhow,1615
84
+ etlplus/file/pbf.py,sha256=lcdehGK_g2drs0VFqTAxZO9-sv65SAkW894ttmlBG8I,1620
85
+ etlplus/file/properties.py,sha256=zsdaIWbSGGXH1bvlI8XPtc0eQCb-CeeA5CHJaqupNrE,1718
86
+ etlplus/file/proto.py,sha256=QnZMGYHmr6jyiQ08W7hx_MHzNDrPEmMmnbttNRlY4Pg,1668
87
+ etlplus/file/psv.py,sha256=-pfGvLSNOMWVl1mGoKJ_Rh5p5wDyCaxLEd09U23Iub0,1726
88
+ etlplus/file/rda.py,sha256=oFbnf6SQrbgKdNDvQ94aeubwVlSEY0K_2BMIEqp22pY,1668
89
+ etlplus/file/rds.py,sha256=9E2IfTaI6XRqfwdy-m-6laG7cTq9tlm8kMhldLJznPw,1625
90
+ etlplus/file/sas7bdat.py,sha256=y_SOBwGPksIvMdO60PoYIVrmppWKvZQfhJSHMABDDlg,1706
91
+ etlplus/file/sav.py,sha256=9cd1curI6gkhXNJPTQP30CUwXdH45qGmPau5JCNmxqg,1597
92
+ etlplus/file/sqlite.py,sha256=3YRGMB5cRwdZeUVq3J_jSKauad7s8wWHWviqx7yfrUw,1652
93
+ etlplus/file/stub.py,sha256=UPiKD_CYkz66X6bZtSqWX3ShBFrMlf-Se83z4qYnIR4,1733
94
+ etlplus/file/sylk.py,sha256=ZqWNAuJenydVYG75a4atRtSQ1iPAscvx-v6lUqdDqvg,1657
95
+ etlplus/file/tab.py,sha256=yIbgIM8jkbOmCmewYnDeL4751tHSjVszMIxNlm9C3q8,1984
96
+ etlplus/file/toml.py,sha256=Z9UgUJ-PKdlA78osRyARK5AVN7AepSuq4dbUUXTGNAE,1626
97
+ etlplus/file/tsv.py,sha256=hKlJd8Q7waZs9_jhRANhmb-fQdPsbvaVG46gYuNVtq0,1766
98
+ etlplus/file/txt.py,sha256=46gSCxPn3SsixtR3RQ-kziaY5cnApHgRbW7UP__9ryE,2313
99
+ etlplus/file/vm.py,sha256=_EiHtFOxcSwoLb5qegZ0sDr5z9TwKQPbB-MQolb6I2A,1589
100
+ etlplus/file/wks.py,sha256=QwsjgcIpaYMZb-NEzgNSRKdBEqhahuoTeAVA5VEmsag,1655
101
+ etlplus/file/xls.py,sha256=P94lEH8ZMex_G5x1hotidcj-dvGHAnUY7ouzvSYaV7o,1772
102
+ etlplus/file/xlsm.py,sha256=6meoukAvpEIm_mvVomIo2oefPYfmHHXfE1XmFfeFpvY,1738
103
+ etlplus/file/xlsx.py,sha256=vtiAS8Ng9FV1vCWYTd1YO2ORKIJG3HDfmqy3NkVpt0A,2182
104
+ etlplus/file/xml.py,sha256=p5P60DiV6hyiz-t970d0d0ZXB41gVvAm3MT7dTMULa8,4360
105
+ etlplus/file/xpt.py,sha256=JLqOkZ60awNsPXSqLKcPUwqZLPhPR05zk4EVRdEfvoU,1702
106
+ etlplus/file/yaml.py,sha256=P9xzginPVVyvIPbFAp6MYWwARhK50GzgMbjZB7HwOrs,2052
107
+ etlplus/file/zip.py,sha256=nd26V3S0edklriKnKOGDTLlO8RBXTda_zLLEQrJgKL4,4185
108
+ etlplus/file/zsav.py,sha256=2WxjXamvzj0adDbWGMWM3-cj_LsCRjyZz4J907lNkPk,1664
109
+ etlplus/ops/README.md,sha256=8omi7DYZhelc26JKk8Cm8QR8I3OGwziysPj1ivx41iQ,1380
110
+ etlplus/ops/__init__.py,sha256=NIIr2f-AZj5B0piBt6gjv46Yn0SzGYxEe6BPoopRh38,1702
111
+ etlplus/ops/extract.py,sha256=OJozX25qTjME7m9aTdVPJScT3GHHgopGM8uHo_rHm1Y,5783
112
+ etlplus/ops/load.py,sha256=RgEKnVygRN2cPDpzihU8UsIhd4eVoj0cPe0jBuNC0u4,8328
113
+ etlplus/ops/run.py,sha256=JOPQxrciRUQ67FJhUcZ-pW1aiYGZUdxHLwhzWLNCaDo,13528
114
+ etlplus/ops/transform.py,sha256=1P43WYUaw872JDU86FhbbbkP8xnBWpgEPn2Q-z4ywls,25421
115
+ etlplus/ops/utils.py,sha256=mNUcbnLl3M6rA_BPoUqG-IFPqT1zrp_EkQTs7uvzBIQ,10839
116
+ etlplus/ops/validate.py,sha256=-OLAwQNNCmmDbmj0SB7zzYXDkJfcyBP_z9nTpqImLP0,13271
117
+ etlplus/templates/README.md,sha256=IfPXlj1TGVA-uFWosHJhE2rabFW-znxOlOMazO9Z5cE,1361
118
+ etlplus/templates/__init__.py,sha256=tsniN7XJYs3NwYxJ6c2HD5upHP3CDkLx-bQCMt97UOM,106
119
+ etlplus/templates/ddl.sql.j2,sha256=s8fMWvcb4eaJVXkifuib1aQPljtZ8buuyB_uA-ZdU3Q,4734
120
+ etlplus/templates/view.sql.j2,sha256=Iy8DHfhq5yyvrUKDxqp_aHIEXY4Tm6j4wT7YDEFWAhk,2180
121
+ etlplus/workflow/README.md,sha256=D1oloiJCOHiqpqgv3m3qpRSIUOMIQcWtIsOPv7KkNI0,1652
122
+ etlplus/workflow/__init__.py,sha256=LxI9VGlDBUc9ADoK8JNn3oVsGeaz1Uhjonn4Y5KIJdM,967
123
+ etlplus/workflow/connector.py,sha256=vnzq9-qcU4ThWeI3ZJcL8iCoaKWrSEtZ9Jixn4il2KE,9995
124
+ etlplus/workflow/dag.py,sha256=kp31dORgk0GHbct_bipU5hu_0elwBtwLsXGjMWuhFHI,2503
125
+ etlplus/workflow/jobs.py,sha256=5_jhPoT2hCGTgsbK_lIPKrB94f7tzOEUJxtU3tpvTjg,8947
126
+ etlplus/workflow/pipeline.py,sha256=eF6OYMXZ_YdDPZ5FJC6OTCAM-zsb8HxhX3IHpbb_N8w,9631
127
+ etlplus/workflow/profile.py,sha256=dZ6P50k_ZqXnrbgrbODUqgVkymbchcEqfZR-ExjTd3M,1935
128
+ etlplus/workflow/types.py,sha256=Lv1MLyM45Ob5AsMQQBqzbUaD8g7HMVxu_HoQGPeiugU,2771
129
+ etlplus-0.9.2.dist-info/licenses/LICENSE,sha256=MuNO63i6kWmgnV2pbP2SLqP54mk1BGmu7CmbtxMmT-U,1069
130
+ etlplus-0.9.2.dist-info/METADATA,sha256=3wCUIvTSgSYH0AJeFIrHVniFGXaohQwhKHzX74ew5ZA,28113
131
+ etlplus-0.9.2.dist-info/WHEEL,sha256=qELbo2s1Yzl39ZmrAibXA2jjPLUYfnVhUNTlyF1rq0Y,92
132
+ etlplus-0.9.2.dist-info/entry_points.txt,sha256=6w-2-jzuPa55spzK34h-UKh2JTEShh38adFRONNP9QE,45
133
+ etlplus-0.9.2.dist-info/top_level.txt,sha256=aWWF-udn_sLGuHTM6W6MLh99ArS9ROkUWO8Mi8y1_2U,8
134
+ etlplus-0.9.2.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