etlplus 0.5.2__tar.gz → 0.5.4__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.
Files changed (136) hide show
  1. {etlplus-0.5.2/etlplus.egg-info → etlplus-0.5.4}/PKG-INFO +17 -9
  2. {etlplus-0.5.2 → etlplus-0.5.4}/README.md +16 -8
  3. {etlplus-0.5.2 → etlplus-0.5.4}/docs/pipeline-guide.md +4 -4
  4. {etlplus-0.5.2 → etlplus-0.5.4}/etlplus/cli/app.py +185 -185
  5. {etlplus-0.5.2 → etlplus-0.5.4}/etlplus/cli/handlers.py +113 -109
  6. {etlplus-0.5.2 → etlplus-0.5.4}/etlplus/cli/main.py +12 -12
  7. {etlplus-0.5.2 → etlplus-0.5.4/etlplus.egg-info}/PKG-INFO +17 -9
  8. {etlplus-0.5.2 → etlplus-0.5.4}/examples/README.md +2 -2
  9. {etlplus-0.5.2 → etlplus-0.5.4}/tests/unit/cli/test_u_cli_app.py +24 -24
  10. {etlplus-0.5.2 → etlplus-0.5.4}/tests/unit/cli/test_u_cli_handlers.py +46 -46
  11. {etlplus-0.5.2 → etlplus-0.5.4}/tests/unit/cli/test_u_cli_main.py +11 -5
  12. {etlplus-0.5.2 → etlplus-0.5.4}/.coveragerc +0 -0
  13. {etlplus-0.5.2 → etlplus-0.5.4}/.editorconfig +0 -0
  14. {etlplus-0.5.2 → etlplus-0.5.4}/.gitattributes +0 -0
  15. {etlplus-0.5.2 → etlplus-0.5.4}/.github/actions/python-bootstrap/action.yml +0 -0
  16. {etlplus-0.5.2 → etlplus-0.5.4}/.github/workflows/ci.yml +0 -0
  17. {etlplus-0.5.2 → etlplus-0.5.4}/.gitignore +0 -0
  18. {etlplus-0.5.2 → etlplus-0.5.4}/.pre-commit-config.yaml +0 -0
  19. {etlplus-0.5.2 → etlplus-0.5.4}/.ruff.toml +0 -0
  20. {etlplus-0.5.2 → etlplus-0.5.4}/CODE_OF_CONDUCT.md +0 -0
  21. {etlplus-0.5.2 → etlplus-0.5.4}/CONTRIBUTING.md +0 -0
  22. {etlplus-0.5.2 → etlplus-0.5.4}/DEMO.md +0 -0
  23. {etlplus-0.5.2 → etlplus-0.5.4}/LICENSE +0 -0
  24. {etlplus-0.5.2 → etlplus-0.5.4}/MANIFEST.in +0 -0
  25. {etlplus-0.5.2 → etlplus-0.5.4}/Makefile +0 -0
  26. {etlplus-0.5.2 → etlplus-0.5.4}/REFERENCES.md +0 -0
  27. {etlplus-0.5.2 → etlplus-0.5.4}/docs/snippets/installation_version.md +0 -0
  28. {etlplus-0.5.2 → etlplus-0.5.4}/etlplus/__init__.py +0 -0
  29. {etlplus-0.5.2 → etlplus-0.5.4}/etlplus/__main__.py +0 -0
  30. {etlplus-0.5.2 → etlplus-0.5.4}/etlplus/__version__.py +0 -0
  31. {etlplus-0.5.2 → etlplus-0.5.4}/etlplus/api/README.md +0 -0
  32. {etlplus-0.5.2 → etlplus-0.5.4}/etlplus/api/__init__.py +0 -0
  33. {etlplus-0.5.2 → etlplus-0.5.4}/etlplus/api/auth.py +0 -0
  34. {etlplus-0.5.2 → etlplus-0.5.4}/etlplus/api/config.py +0 -0
  35. {etlplus-0.5.2 → etlplus-0.5.4}/etlplus/api/endpoint_client.py +0 -0
  36. {etlplus-0.5.2 → etlplus-0.5.4}/etlplus/api/errors.py +0 -0
  37. {etlplus-0.5.2 → etlplus-0.5.4}/etlplus/api/pagination/__init__.py +0 -0
  38. {etlplus-0.5.2 → etlplus-0.5.4}/etlplus/api/pagination/client.py +0 -0
  39. {etlplus-0.5.2 → etlplus-0.5.4}/etlplus/api/pagination/config.py +0 -0
  40. {etlplus-0.5.2 → etlplus-0.5.4}/etlplus/api/pagination/paginator.py +0 -0
  41. {etlplus-0.5.2 → etlplus-0.5.4}/etlplus/api/rate_limiting/__init__.py +0 -0
  42. {etlplus-0.5.2 → etlplus-0.5.4}/etlplus/api/rate_limiting/config.py +0 -0
  43. {etlplus-0.5.2 → etlplus-0.5.4}/etlplus/api/rate_limiting/rate_limiter.py +0 -0
  44. {etlplus-0.5.2 → etlplus-0.5.4}/etlplus/api/request_manager.py +0 -0
  45. {etlplus-0.5.2 → etlplus-0.5.4}/etlplus/api/retry_manager.py +0 -0
  46. {etlplus-0.5.2 → etlplus-0.5.4}/etlplus/api/transport.py +0 -0
  47. {etlplus-0.5.2 → etlplus-0.5.4}/etlplus/api/types.py +0 -0
  48. {etlplus-0.5.2 → etlplus-0.5.4}/etlplus/cli/__init__.py +0 -0
  49. {etlplus-0.5.2 → etlplus-0.5.4}/etlplus/config/__init__.py +0 -0
  50. {etlplus-0.5.2 → etlplus-0.5.4}/etlplus/config/connector.py +0 -0
  51. {etlplus-0.5.2 → etlplus-0.5.4}/etlplus/config/jobs.py +0 -0
  52. {etlplus-0.5.2 → etlplus-0.5.4}/etlplus/config/pipeline.py +0 -0
  53. {etlplus-0.5.2 → etlplus-0.5.4}/etlplus/config/profile.py +0 -0
  54. {etlplus-0.5.2 → etlplus-0.5.4}/etlplus/config/types.py +0 -0
  55. {etlplus-0.5.2 → etlplus-0.5.4}/etlplus/config/utils.py +0 -0
  56. {etlplus-0.5.2 → etlplus-0.5.4}/etlplus/ddl.py +0 -0
  57. {etlplus-0.5.2 → etlplus-0.5.4}/etlplus/enums.py +0 -0
  58. {etlplus-0.5.2 → etlplus-0.5.4}/etlplus/extract.py +0 -0
  59. {etlplus-0.5.2 → etlplus-0.5.4}/etlplus/file.py +0 -0
  60. {etlplus-0.5.2 → etlplus-0.5.4}/etlplus/load.py +0 -0
  61. {etlplus-0.5.2 → etlplus-0.5.4}/etlplus/mixins.py +0 -0
  62. {etlplus-0.5.2 → etlplus-0.5.4}/etlplus/py.typed +0 -0
  63. {etlplus-0.5.2 → etlplus-0.5.4}/etlplus/run.py +0 -0
  64. {etlplus-0.5.2 → etlplus-0.5.4}/etlplus/run_helpers.py +0 -0
  65. {etlplus-0.5.2 → etlplus-0.5.4}/etlplus/templates/__init__.py +0 -0
  66. {etlplus-0.5.2 → etlplus-0.5.4}/etlplus/templates/ddl.sql.j2 +0 -0
  67. {etlplus-0.5.2 → etlplus-0.5.4}/etlplus/templates/view.sql.j2 +0 -0
  68. {etlplus-0.5.2 → etlplus-0.5.4}/etlplus/transform.py +0 -0
  69. {etlplus-0.5.2 → etlplus-0.5.4}/etlplus/types.py +0 -0
  70. {etlplus-0.5.2 → etlplus-0.5.4}/etlplus/utils.py +0 -0
  71. {etlplus-0.5.2 → etlplus-0.5.4}/etlplus/validate.py +0 -0
  72. {etlplus-0.5.2 → etlplus-0.5.4}/etlplus/validation/__init__.py +0 -0
  73. {etlplus-0.5.2 → etlplus-0.5.4}/etlplus/validation/utils.py +0 -0
  74. {etlplus-0.5.2 → etlplus-0.5.4}/etlplus.egg-info/SOURCES.txt +0 -0
  75. {etlplus-0.5.2 → etlplus-0.5.4}/etlplus.egg-info/dependency_links.txt +0 -0
  76. {etlplus-0.5.2 → etlplus-0.5.4}/etlplus.egg-info/entry_points.txt +0 -0
  77. {etlplus-0.5.2 → etlplus-0.5.4}/etlplus.egg-info/requires.txt +0 -0
  78. {etlplus-0.5.2 → etlplus-0.5.4}/etlplus.egg-info/top_level.txt +0 -0
  79. {etlplus-0.5.2 → etlplus-0.5.4}/examples/configs/ddl_spec.yml +0 -0
  80. {etlplus-0.5.2 → etlplus-0.5.4}/examples/configs/pipeline.yml +0 -0
  81. {etlplus-0.5.2 → etlplus-0.5.4}/examples/data/sample.csv +0 -0
  82. {etlplus-0.5.2 → etlplus-0.5.4}/examples/data/sample.json +0 -0
  83. {etlplus-0.5.2 → etlplus-0.5.4}/examples/data/sample.xml +0 -0
  84. {etlplus-0.5.2 → etlplus-0.5.4}/examples/data/sample.xsd +0 -0
  85. {etlplus-0.5.2 → etlplus-0.5.4}/examples/data/sample.yaml +0 -0
  86. {etlplus-0.5.2 → etlplus-0.5.4}/examples/quickstart_python.py +0 -0
  87. {etlplus-0.5.2 → etlplus-0.5.4}/pyproject.toml +0 -0
  88. {etlplus-0.5.2 → etlplus-0.5.4}/pytest.ini +0 -0
  89. {etlplus-0.5.2 → etlplus-0.5.4}/setup.cfg +0 -0
  90. {etlplus-0.5.2 → etlplus-0.5.4}/setup.py +0 -0
  91. {etlplus-0.5.2 → etlplus-0.5.4}/tests/__init__.py +0 -0
  92. {etlplus-0.5.2 → etlplus-0.5.4}/tests/conftest.py +0 -0
  93. {etlplus-0.5.2 → etlplus-0.5.4}/tests/integration/conftest.py +0 -0
  94. {etlplus-0.5.2 → etlplus-0.5.4}/tests/integration/test_i_cli.py +0 -0
  95. {etlplus-0.5.2 → etlplus-0.5.4}/tests/integration/test_i_examples_data_parity.py +0 -0
  96. {etlplus-0.5.2 → etlplus-0.5.4}/tests/integration/test_i_pagination_strategy.py +0 -0
  97. {etlplus-0.5.2 → etlplus-0.5.4}/tests/integration/test_i_pipeline_smoke.py +0 -0
  98. {etlplus-0.5.2 → etlplus-0.5.4}/tests/integration/test_i_pipeline_yaml_load.py +0 -0
  99. {etlplus-0.5.2 → etlplus-0.5.4}/tests/integration/test_i_run.py +0 -0
  100. {etlplus-0.5.2 → etlplus-0.5.4}/tests/integration/test_i_run_profile_pagination_defaults.py +0 -0
  101. {etlplus-0.5.2 → etlplus-0.5.4}/tests/integration/test_i_run_profile_rate_limit_defaults.py +0 -0
  102. {etlplus-0.5.2 → etlplus-0.5.4}/tests/unit/api/conftest.py +0 -0
  103. {etlplus-0.5.2 → etlplus-0.5.4}/tests/unit/api/test_u_auth.py +0 -0
  104. {etlplus-0.5.2 → etlplus-0.5.4}/tests/unit/api/test_u_config.py +0 -0
  105. {etlplus-0.5.2 → etlplus-0.5.4}/tests/unit/api/test_u_endpoint_client.py +0 -0
  106. {etlplus-0.5.2 → etlplus-0.5.4}/tests/unit/api/test_u_mocks.py +0 -0
  107. {etlplus-0.5.2 → etlplus-0.5.4}/tests/unit/api/test_u_pagination_client.py +0 -0
  108. {etlplus-0.5.2 → etlplus-0.5.4}/tests/unit/api/test_u_pagination_config.py +0 -0
  109. {etlplus-0.5.2 → etlplus-0.5.4}/tests/unit/api/test_u_paginator.py +0 -0
  110. {etlplus-0.5.2 → etlplus-0.5.4}/tests/unit/api/test_u_rate_limit_config.py +0 -0
  111. {etlplus-0.5.2 → etlplus-0.5.4}/tests/unit/api/test_u_rate_limiter.py +0 -0
  112. {etlplus-0.5.2 → etlplus-0.5.4}/tests/unit/api/test_u_request_manager.py +0 -0
  113. {etlplus-0.5.2 → etlplus-0.5.4}/tests/unit/api/test_u_retry_manager.py +0 -0
  114. {etlplus-0.5.2 → etlplus-0.5.4}/tests/unit/api/test_u_transport.py +0 -0
  115. {etlplus-0.5.2 → etlplus-0.5.4}/tests/unit/api/test_u_types.py +0 -0
  116. {etlplus-0.5.2 → etlplus-0.5.4}/tests/unit/cli/conftest.py +0 -0
  117. {etlplus-0.5.2 → etlplus-0.5.4}/tests/unit/config/test_u_config_utils.py +0 -0
  118. {etlplus-0.5.2 → etlplus-0.5.4}/tests/unit/config/test_u_connector.py +0 -0
  119. {etlplus-0.5.2 → etlplus-0.5.4}/tests/unit/config/test_u_jobs.py +0 -0
  120. {etlplus-0.5.2 → etlplus-0.5.4}/tests/unit/config/test_u_pipeline.py +0 -0
  121. {etlplus-0.5.2 → etlplus-0.5.4}/tests/unit/conftest.py +0 -0
  122. {etlplus-0.5.2 → etlplus-0.5.4}/tests/unit/test_u_enums.py +0 -0
  123. {etlplus-0.5.2 → etlplus-0.5.4}/tests/unit/test_u_extract.py +0 -0
  124. {etlplus-0.5.2 → etlplus-0.5.4}/tests/unit/test_u_file.py +0 -0
  125. {etlplus-0.5.2 → etlplus-0.5.4}/tests/unit/test_u_load.py +0 -0
  126. {etlplus-0.5.2 → etlplus-0.5.4}/tests/unit/test_u_main.py +0 -0
  127. {etlplus-0.5.2 → etlplus-0.5.4}/tests/unit/test_u_mixins.py +0 -0
  128. {etlplus-0.5.2 → etlplus-0.5.4}/tests/unit/test_u_run.py +0 -0
  129. {etlplus-0.5.2 → etlplus-0.5.4}/tests/unit/test_u_run_helpers.py +0 -0
  130. {etlplus-0.5.2 → etlplus-0.5.4}/tests/unit/test_u_transform.py +0 -0
  131. {etlplus-0.5.2 → etlplus-0.5.4}/tests/unit/test_u_utils.py +0 -0
  132. {etlplus-0.5.2 → etlplus-0.5.4}/tests/unit/test_u_validate.py +0 -0
  133. {etlplus-0.5.2 → etlplus-0.5.4}/tests/unit/test_u_version.py +0 -0
  134. {etlplus-0.5.2 → etlplus-0.5.4}/tests/unit/validation/test_u_validation_utils.py +0 -0
  135. {etlplus-0.5.2 → etlplus-0.5.4}/tools/run_pipeline.py +0 -0
  136. {etlplus-0.5.2 → etlplus-0.5.4}/tools/update_demo_snippets.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: etlplus
3
- Version: 0.5.2
3
+ Version: 0.5.4
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
@@ -90,6 +90,14 @@ package and command-line interface for data extraction, validation, transformati
90
90
 
91
91
  ## Features
92
92
 
93
+ - **Check** data pipeline definitions before running them:
94
+ - Summarize jobs, sources, targets, and transforms
95
+ - Confirm configuration changes by printing focused sections on demand
96
+
97
+ - **Render** SQL DDL from shared table specs:
98
+ - Generate CREATE TABLE or view statements
99
+ - Swap templates or direct output to files for database migrations
100
+
93
101
  - **Extract** data from multiple sources:
94
102
  - Files (CSV, JSON, XML, YAML)
95
103
  - Databases (connection string support)
@@ -171,21 +179,21 @@ etlplus --help
171
179
  etlplus --version
172
180
  ```
173
181
 
174
- #### Inspect Pipelines
182
+ #### Check Pipelines
175
183
 
176
- Use `etlplus list` to explore pipeline YAML definitions without running them. The command can print
184
+ Use `etlplus check` to explore pipeline YAML definitions without running them. The command can print
177
185
  job names, summarize configured sources and targets, or drill into specific sections.
178
186
 
179
187
  List jobs and show a pipeline summary:
180
188
  ```bash
181
- etlplus list --config examples/configs/pipeline.yml --jobs
182
- etlplus list --config examples/configs/pipeline.yml --summary
189
+ etlplus check --config examples/configs/pipeline.yml --jobs
190
+ etlplus check --config examples/configs/pipeline.yml --summary
183
191
  ```
184
192
 
185
193
  Show sources or transforms for troubleshooting:
186
194
  ```bash
187
- etlplus list --config examples/configs/pipeline.yml --sources
188
- etlplus list --config examples/configs/pipeline.yml --transforms
195
+ etlplus check --config examples/configs/pipeline.yml --sources
196
+ etlplus check --config examples/configs/pipeline.yml --transforms
189
197
  ```
190
198
 
191
199
  #### Render SQL DDL
@@ -350,8 +358,8 @@ CLI quick reference for pipelines:
350
358
 
351
359
  ```bash
352
360
  # List jobs or show a pipeline summary
353
- etlplus list --config examples/configs/pipeline.yml --jobs
354
- etlplus list --config examples/configs/pipeline.yml --summary
361
+ etlplus check --config examples/configs/pipeline.yml --jobs
362
+ etlplus check --config examples/configs/pipeline.yml --summary
355
363
 
356
364
  # Run a job
357
365
  etlplus run --config examples/configs/pipeline.yml --job file_to_file_customers
@@ -48,6 +48,14 @@ package and command-line interface for data extraction, validation, transformati
48
48
 
49
49
  ## Features
50
50
 
51
+ - **Check** data pipeline definitions before running them:
52
+ - Summarize jobs, sources, targets, and transforms
53
+ - Confirm configuration changes by printing focused sections on demand
54
+
55
+ - **Render** SQL DDL from shared table specs:
56
+ - Generate CREATE TABLE or view statements
57
+ - Swap templates or direct output to files for database migrations
58
+
51
59
  - **Extract** data from multiple sources:
52
60
  - Files (CSV, JSON, XML, YAML)
53
61
  - Databases (connection string support)
@@ -129,21 +137,21 @@ etlplus --help
129
137
  etlplus --version
130
138
  ```
131
139
 
132
- #### Inspect Pipelines
140
+ #### Check Pipelines
133
141
 
134
- Use `etlplus list` to explore pipeline YAML definitions without running them. The command can print
142
+ Use `etlplus check` to explore pipeline YAML definitions without running them. The command can print
135
143
  job names, summarize configured sources and targets, or drill into specific sections.
136
144
 
137
145
  List jobs and show a pipeline summary:
138
146
  ```bash
139
- etlplus list --config examples/configs/pipeline.yml --jobs
140
- etlplus list --config examples/configs/pipeline.yml --summary
147
+ etlplus check --config examples/configs/pipeline.yml --jobs
148
+ etlplus check --config examples/configs/pipeline.yml --summary
141
149
  ```
142
150
 
143
151
  Show sources or transforms for troubleshooting:
144
152
  ```bash
145
- etlplus list --config examples/configs/pipeline.yml --sources
146
- etlplus list --config examples/configs/pipeline.yml --transforms
153
+ etlplus check --config examples/configs/pipeline.yml --sources
154
+ etlplus check --config examples/configs/pipeline.yml --transforms
147
155
  ```
148
156
 
149
157
  #### Render SQL DDL
@@ -308,8 +316,8 @@ CLI quick reference for pipelines:
308
316
 
309
317
  ```bash
310
318
  # List jobs or show a pipeline summary
311
- etlplus list --config examples/configs/pipeline.yml --jobs
312
- etlplus list --config examples/configs/pipeline.yml --summary
319
+ etlplus check --config examples/configs/pipeline.yml --jobs
320
+ etlplus check --config examples/configs/pipeline.yml --summary
313
321
 
314
322
  # Run a job
315
323
  etlplus run --config examples/configs/pipeline.yml --job file_to_file_customers
@@ -378,13 +378,13 @@ jobs:
378
378
  Once you have a pipeline YAML, you can run jobs either from the
379
379
  command line or directly from Python.
380
380
 
381
- ### CLI: `etlplus list` (inspect) and `etlplus run` (execute)
381
+ ### CLI: `etlplus check` (inspect) and `etlplus run` (execute)
382
382
 
383
383
  List jobs or show a summary from a pipeline file:
384
384
 
385
385
  ```bash
386
- etlplus list --config examples/configs/pipeline.yml --jobs
387
- etlplus list --config examples/configs/pipeline.yml --summary
386
+ etlplus check --config examples/configs/pipeline.yml --jobs
387
+ etlplus check --config examples/configs/pipeline.yml --summary
388
388
  ```
389
389
 
390
390
  Run a specific job end-to-end (extract → validate → transform → load):
@@ -402,7 +402,7 @@ Notes:
402
402
  [Runner internals: etlplus.run](run-module.md).
403
403
 
404
404
  Deprecated: `etlplus pipeline` is still available as a shim but will be removed in a future release;
405
- prefer `list` and `run`.
405
+ prefer `check` and `run`.
406
406
 
407
407
  ### Python: `etlplus.run.run`
408
408
 
@@ -57,8 +57,8 @@ from .. import __version__
57
57
  from ..enums import DataConnectorType
58
58
  from ..enums import FileFormat
59
59
  from ..utils import json_type
60
+ from .handlers import cmd_check
60
61
  from .handlers import cmd_extract
61
- from .handlers import cmd_list
62
62
  from .handlers import cmd_load
63
63
  from .handlers import cmd_pipeline
64
64
  from .handlers import cmd_render
@@ -127,109 +127,82 @@ PROJECT_URL: Final[str] = 'https://github.com/Dagitali/ETLPlus'
127
127
  # SECTION: TYPE ALIASES ==================================================== #
128
128
 
129
129
 
130
- SourceInputArg = Annotated[
131
- str,
132
- typer.Argument(
133
- ...,
134
- metavar='SOURCE',
135
- help=(
136
- 'Extract from SOURCE. Use --from/--source-type to override the '
137
- 'inferred connector when needed.'
138
- ),
139
- ),
140
- ]
141
-
142
- StreamingSourceArg = Annotated[
130
+ OperationsJSONOption = Annotated[
143
131
  str,
144
- typer.Argument(
145
- ...,
146
- metavar='SOURCE',
147
- help=(
148
- 'Data source to transform or validate (path, JSON payload, or '
149
- '- for stdin).'
150
- ),
132
+ typer.Option(
133
+ '--operations',
134
+ help='Transformation operations as JSON string.',
151
135
  ),
152
136
  ]
153
137
 
154
- TargetInputArg = Annotated[
138
+ PipelineConfigOption = Annotated[
155
139
  str,
156
- typer.Argument(
140
+ typer.Option(
157
141
  ...,
158
- metavar='TARGET',
159
- help=(
160
- 'Load JSON data from stdin into TARGET. Use --to/--target-type '
161
- 'to override connector inference when needed. Source data must '
162
- 'be piped into stdin.'
163
- ),
142
+ '--config',
143
+ metavar='PATH',
144
+ help='Path to pipeline YAML configuration file.',
164
145
  ),
165
146
  ]
166
147
 
167
- SourceOverrideOption = Annotated[
148
+ RenderConfigOption = Annotated[
168
149
  str | None,
169
150
  typer.Option(
170
- '--source-type',
171
- metavar='CONNECTOR',
151
+ '--config',
152
+ metavar='PATH',
153
+ help='Pipeline YAML that includes table_schemas for rendering.',
172
154
  show_default=False,
173
- rich_help_panel='I/O overrides',
174
- help='Override the inferred source type (file, database, api).',
175
155
  ),
176
156
  ]
177
157
 
178
- TargetOverrideOption = Annotated[
158
+ RenderOutputOption = Annotated[
179
159
  str | None,
180
160
  typer.Option(
181
- '--target-type',
182
- metavar='CONNECTOR',
183
- show_default=False,
184
- rich_help_panel='I/O overrides',
185
- help='Override the inferred target type (file, database, api).',
161
+ '--output',
162
+ '-o',
163
+ metavar='PATH',
164
+ help='Write rendered SQL to PATH (default: stdout).',
186
165
  ),
187
166
  ]
188
167
 
189
- SourceFormatOption = Annotated[
168
+ RenderSpecOption = Annotated[
190
169
  str | None,
191
170
  typer.Option(
192
- '--source-format',
193
- metavar='FORMAT',
171
+ '--spec',
172
+ metavar='PATH',
173
+ help='Standalone table spec file (.yml/.yaml/.json).',
194
174
  show_default=False,
195
- rich_help_panel='Format overrides',
196
- help=(
197
- 'Input payload format when SOURCE is - or an inline payload. '
198
- 'File sources infer format from the extension.'
199
- ),
200
175
  ),
201
176
  ]
202
177
 
203
- StdinFormatOption = Annotated[
178
+ RenderTableOption = Annotated[
204
179
  str | None,
205
180
  typer.Option(
206
- '--source-format',
207
- metavar='FORMAT',
208
- show_default=False,
209
- rich_help_panel='Format overrides',
210
- help='Input payload format when reading from stdin (default: json).',
181
+ '--table',
182
+ metavar='NAME',
183
+ help='Filter to a single table name from table_schemas.',
211
184
  ),
212
185
  ]
213
186
 
214
- TargetFormatOption = Annotated[
215
- str | None,
187
+ RenderTemplateOption = Annotated[
188
+ str,
216
189
  typer.Option(
217
- '--target-format',
218
- metavar='FORMAT',
219
- show_default=False,
220
- rich_help_panel='Format overrides',
221
- help=(
222
- 'Payload format when TARGET is - or a non-file connector. File '
223
- 'targets infer format from the extension.'
224
- ),
190
+ '--template',
191
+ '-t',
192
+ metavar='KEY|PATH',
193
+ help='Template key (ddl/view) or path to a Jinja template file.',
194
+ show_default=True,
225
195
  ),
226
196
  ]
227
197
 
228
- OperationsJSONOption = Annotated[
229
- str,
198
+ RenderTemplatePathOption = Annotated[
199
+ str | None,
230
200
  typer.Option(
231
- '--operations',
232
- help='Transformation operations as JSON string.',
201
+ '--template-path',
202
+ metavar='PATH',
203
+ help=(
204
+ 'Explicit path to a Jinja template file (overrides template key).'
205
+ ),
233
206
  ),
234
207
  ]
235
208
 
@@ -241,83 +214,110 @@ RulesJSONOption = Annotated[
241
214
  ),
242
215
  ]
243
216
 
244
- TargetPathOption = Annotated[
217
+ SourceFormatOption = Annotated[
245
218
  str | None,
246
219
  typer.Option(
247
- '--target',
248
- metavar='PATH',
249
- help='Target file for transformed or validated output (- for stdout).',
220
+ '--source-format',
221
+ metavar='FORMAT',
222
+ show_default=False,
223
+ rich_help_panel='Format overrides',
224
+ help=(
225
+ 'Input payload format when SOURCE is - or an inline payload. '
226
+ 'File sources infer format from the extension.'
227
+ ),
250
228
  ),
251
229
  ]
252
230
 
253
- PipelineConfigOption = Annotated[
231
+ SourceInputArg = Annotated[
254
232
  str,
255
- typer.Option(
233
+ typer.Argument(
256
234
  ...,
257
- '--config',
258
- metavar='PATH',
259
- help='Path to pipeline YAML configuration file.',
235
+ metavar='SOURCE',
236
+ help=(
237
+ 'Extract from SOURCE. Use --from/--source-type to override the '
238
+ 'inferred connector when needed.'
239
+ ),
260
240
  ),
261
241
  ]
262
242
 
263
- RenderConfigOption = Annotated[
243
+ SourceOverrideOption = Annotated[
264
244
  str | None,
265
245
  typer.Option(
266
- '--config',
267
- metavar='PATH',
268
- help='Pipeline YAML that includes table_schemas for rendering.',
246
+ '--source-type',
247
+ metavar='CONNECTOR',
269
248
  show_default=False,
249
+ rich_help_panel='I/O overrides',
250
+ help='Override the inferred source type (file, database, api).',
270
251
  ),
271
252
  ]
272
253
 
273
- RenderOutputOption = Annotated[
254
+ StdinFormatOption = Annotated[
274
255
  str | None,
275
256
  typer.Option(
276
- '--output',
277
- '-o',
278
- metavar='PATH',
279
- help='Write rendered SQL to PATH (default: stdout).',
257
+ '--source-format',
258
+ metavar='FORMAT',
259
+ show_default=False,
260
+ rich_help_panel='Format overrides',
261
+ help='Input payload format when reading from stdin (default: json).',
280
262
  ),
281
263
  ]
282
264
 
283
- RenderSpecOption = Annotated[
284
- str | None,
285
- typer.Option(
286
- '--spec',
287
- metavar='PATH',
288
- help='Standalone table spec file (.yml/.yaml/.json).',
289
- show_default=False,
265
+ StreamingSourceArg = Annotated[
266
+ str,
267
+ typer.Argument(
268
+ ...,
269
+ metavar='SOURCE',
270
+ help=(
271
+ 'Data source to transform or validate (path, JSON payload, or '
272
+ '- for stdin).'
273
+ ),
290
274
  ),
291
275
  ]
292
276
 
293
- RenderTableOption = Annotated[
277
+ TargetFormatOption = Annotated[
294
278
  str | None,
295
279
  typer.Option(
296
- '--table',
297
- metavar='NAME',
298
- help='Filter to a single table name from table_schemas.',
280
+ '--target-format',
281
+ metavar='FORMAT',
282
+ show_default=False,
283
+ rich_help_panel='Format overrides',
284
+ help=(
285
+ 'Payload format when TARGET is - or a non-file connector. File '
286
+ 'targets infer format from the extension.'
287
+ ),
299
288
  ),
300
289
  ]
301
290
 
302
- RenderTemplateOption = Annotated[
291
+ TargetInputArg = Annotated[
303
292
  str,
293
+ typer.Argument(
294
+ ...,
295
+ metavar='TARGET',
296
+ help=(
297
+ 'Load JSON data from stdin into TARGET. Use --to/--target-type '
298
+ 'to override connector inference when needed. Source data must '
299
+ 'be piped into stdin.'
300
+ ),
301
+ ),
302
+ ]
303
+
304
+ TargetOverrideOption = Annotated[
305
+ str | None,
304
306
  typer.Option(
305
- '--template',
306
- '-t',
307
- metavar='KEY|PATH',
308
- help='Template key (ddl/view) or path to a Jinja template file.',
309
- show_default=True,
307
+ '--target-type',
308
+ metavar='CONNECTOR',
309
+ show_default=False,
310
+ rich_help_panel='I/O overrides',
311
+ help='Override the inferred target type (file, database, api).',
310
312
  ),
311
313
  ]
312
314
 
313
- RenderTemplatePathOption = Annotated[
315
+ TargetPathOption = Annotated[
314
316
  str | None,
315
317
  typer.Option(
316
- '--template-path',
318
+ '--target',
317
319
  metavar='PATH',
318
- help=(
319
- 'Explicit path to a Jinja template file (overrides template key).'
320
- ),
320
+ help='Target file for transformed or validated output (- for stdout).',
321
321
  ),
322
322
  ]
323
323
 
@@ -745,6 +745,83 @@ def _root(
745
745
  raise typer.Exit(0)
746
746
 
747
747
 
748
+ @app.command('check')
749
+ def check_cmd(
750
+ ctx: typer.Context,
751
+ config: PipelineConfigOption,
752
+ jobs: bool = typer.Option(
753
+ False,
754
+ '--jobs',
755
+ help='List available job names and exit',
756
+ ),
757
+ pipelines: bool = typer.Option(
758
+ False,
759
+ '--pipelines',
760
+ help='List ETL pipelines',
761
+ ),
762
+ sources: bool = typer.Option(
763
+ False,
764
+ '--sources',
765
+ help='List data sources',
766
+ ),
767
+ summary: bool = typer.Option(
768
+ False,
769
+ '--summary',
770
+ help='Show pipeline summary (name, version, sources, targets, jobs)',
771
+ ),
772
+ targets: bool = typer.Option(
773
+ False,
774
+ '--targets',
775
+ help='List data targets',
776
+ ),
777
+ transforms: bool = typer.Option(
778
+ False,
779
+ '--transforms',
780
+ help='List data transforms',
781
+ ),
782
+ ) -> int:
783
+ """
784
+ Print ETL entities from a pipeline YAML configuration.
785
+
786
+ Parameters
787
+ ----------
788
+ ctx : typer.Context
789
+ Typer execution context provided to the command.
790
+ config : PipelineConfigOption
791
+ Path to pipeline YAML configuration file.
792
+ jobs : bool, optional
793
+ If True, list available job names and exit.
794
+ pipelines : bool, optional
795
+ If True, list ETL pipelines.
796
+ sources : bool, optional
797
+ If True, list data sources.
798
+ summary : bool, optional
799
+ If True, show pipeline summary (name, version, sources, targets, jobs).
800
+ targets : bool, optional
801
+ If True, list data targets.
802
+ transforms : bool, optional
803
+ If True, list data transforms.
804
+
805
+ Returns
806
+ -------
807
+ int
808
+ Zero on success.
809
+ """
810
+ state = _ensure_state(ctx)
811
+ ns = _stateful_namespace(
812
+ state,
813
+ command='check',
814
+ config=config,
815
+ summary=summary,
816
+ pipelines=pipelines,
817
+ jobs=jobs,
818
+ sources=sources,
819
+ targets=targets,
820
+ transforms=transforms,
821
+ )
822
+ return int(cmd_check(ns))
823
+
824
+
748
825
  @app.command('extract')
749
826
  def extract_cmd(
750
827
  ctx: typer.Context,
@@ -831,83 +908,6 @@ def extract_cmd(
831
908
  return int(cmd_extract(ns))
832
909
 
833
910
 
834
- @app.command('list')
835
- def list_cmd(
836
- ctx: typer.Context,
837
- config: PipelineConfigOption,
838
- jobs: bool = typer.Option(
839
- False,
840
- '--jobs',
841
- help='List available job names and exit',
842
- ),
843
- pipelines: bool = typer.Option(
844
- False,
845
- '--pipelines',
846
- help='List ETL pipelines',
847
- ),
848
- sources: bool = typer.Option(
849
- False,
850
- '--sources',
851
- help='List data sources',
852
- ),
853
- summary: bool = typer.Option(
854
- False,
855
- '--summary',
856
- help='Show pipeline summary (name, version, sources, targets, jobs)',
857
- ),
858
- targets: bool = typer.Option(
859
- False,
860
- '--targets',
861
- help='List data targets',
862
- ),
863
- transforms: bool = typer.Option(
864
- False,
865
- '--transforms',
866
- help='List data transforms',
867
- ),
868
- ) -> int:
869
- """
870
- Print ETL entities from a pipeline YAML configuration.
871
-
872
- Parameters
873
- ----------
874
- ctx : typer.Context
875
- Typer execution context provided to the command.
876
- config : PipelineConfigOption
877
- Path to pipeline YAML configuration file.
878
- jobs : bool, optional
879
- If True, list available job names and exit.
880
- pipelines : bool, optional
881
- If True, list ETL pipelines.
882
- sources : bool, optional
883
- If True, list data sources.
884
- summary : bool, optional
885
- If True, show pipeline summary (name, version, sources, targets, jobs).
886
- targets : bool, optional
887
- If True, list data targets.
888
- transforms : bool, optional
889
- If True, list data transforms.
890
-
891
- Returns
892
- -------
893
- int
894
- Zero on success.
895
- """
896
- state = _ensure_state(ctx)
897
- ns = _stateful_namespace(
898
- state,
899
- command='list',
900
- config=config,
901
- summary=summary,
902
- pipelines=pipelines,
903
- jobs=jobs,
904
- sources=sources,
905
- targets=targets,
906
- transforms=transforms,
907
- )
908
- return int(cmd_list(ns))
909
-
910
-
911
911
  @app.command('load')
912
912
  def load_cmd(
913
913
  ctx: typer.Context,