jerry-thomas 1.0.3__py3-none-any.whl → 2.0.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.
Files changed (194) hide show
  1. datapipeline/analysis/vector/collector.py +0 -1
  2. datapipeline/build/tasks/config.py +0 -2
  3. datapipeline/build/tasks/metadata.py +0 -2
  4. datapipeline/build/tasks/scaler.py +0 -2
  5. datapipeline/build/tasks/schema.py +0 -2
  6. datapipeline/build/tasks/utils.py +0 -2
  7. datapipeline/cli/app.py +201 -81
  8. datapipeline/cli/commands/contract.py +145 -283
  9. datapipeline/cli/commands/demo.py +13 -0
  10. datapipeline/cli/commands/domain.py +4 -4
  11. datapipeline/cli/commands/dto.py +11 -0
  12. datapipeline/cli/commands/filter.py +2 -2
  13. datapipeline/cli/commands/inspect.py +0 -68
  14. datapipeline/cli/commands/list_.py +30 -13
  15. datapipeline/cli/commands/loader.py +11 -0
  16. datapipeline/cli/commands/mapper.py +82 -0
  17. datapipeline/cli/commands/parser.py +45 -0
  18. datapipeline/cli/commands/run_config.py +1 -3
  19. datapipeline/cli/commands/serve_pipeline.py +5 -7
  20. datapipeline/cli/commands/source.py +106 -18
  21. datapipeline/cli/commands/stream.py +292 -0
  22. datapipeline/cli/visuals/common.py +0 -2
  23. datapipeline/cli/visuals/sections.py +0 -2
  24. datapipeline/cli/workspace_utils.py +0 -3
  25. datapipeline/config/context.py +0 -2
  26. datapipeline/config/dataset/feature.py +1 -0
  27. datapipeline/config/metadata.py +0 -2
  28. datapipeline/config/project.py +0 -2
  29. datapipeline/config/resolution.py +10 -2
  30. datapipeline/config/tasks.py +9 -9
  31. datapipeline/domain/feature.py +3 -0
  32. datapipeline/domain/record.py +7 -7
  33. datapipeline/domain/sample.py +0 -2
  34. datapipeline/domain/vector.py +6 -8
  35. datapipeline/integrations/ml/adapter.py +0 -2
  36. datapipeline/integrations/ml/pandas_support.py +0 -2
  37. datapipeline/integrations/ml/rows.py +0 -2
  38. datapipeline/integrations/ml/torch_support.py +0 -2
  39. datapipeline/io/output.py +0 -2
  40. datapipeline/io/serializers.py +26 -16
  41. datapipeline/mappers/synthetic/time.py +9 -2
  42. datapipeline/pipeline/artifacts.py +3 -5
  43. datapipeline/pipeline/observability.py +0 -2
  44. datapipeline/pipeline/pipelines.py +118 -34
  45. datapipeline/pipeline/stages.py +54 -18
  46. datapipeline/pipeline/utils/spool_cache.py +142 -0
  47. datapipeline/pipeline/utils/transform_utils.py +27 -2
  48. datapipeline/services/artifacts.py +1 -4
  49. datapipeline/services/constants.py +1 -0
  50. datapipeline/services/factories.py +4 -6
  51. datapipeline/services/paths.py +10 -1
  52. datapipeline/services/project_paths.py +0 -2
  53. datapipeline/services/runs.py +0 -2
  54. datapipeline/services/scaffold/contract_yaml.py +76 -0
  55. datapipeline/services/scaffold/demo.py +141 -0
  56. datapipeline/services/scaffold/discovery.py +115 -0
  57. datapipeline/services/scaffold/domain.py +21 -13
  58. datapipeline/services/scaffold/dto.py +31 -0
  59. datapipeline/services/scaffold/filter.py +2 -1
  60. datapipeline/services/scaffold/layout.py +96 -0
  61. datapipeline/services/scaffold/loader.py +61 -0
  62. datapipeline/services/scaffold/mapper.py +116 -0
  63. datapipeline/services/scaffold/parser.py +56 -0
  64. datapipeline/services/scaffold/plugin.py +14 -2
  65. datapipeline/services/scaffold/source_yaml.py +91 -0
  66. datapipeline/services/scaffold/stream_plan.py +129 -0
  67. datapipeline/services/scaffold/utils.py +187 -0
  68. datapipeline/sources/data_loader.py +0 -2
  69. datapipeline/sources/decoders.py +49 -8
  70. datapipeline/sources/factory.py +9 -6
  71. datapipeline/sources/foreach.py +18 -3
  72. datapipeline/sources/synthetic/time/parser.py +1 -1
  73. datapipeline/sources/transports.py +10 -4
  74. datapipeline/templates/demo_skeleton/demo/contracts/equity.ohlcv.yaml +33 -0
  75. datapipeline/templates/demo_skeleton/demo/contracts/time.ticks.hour_sin.yaml +22 -0
  76. datapipeline/templates/demo_skeleton/demo/contracts/time.ticks.linear.yaml +22 -0
  77. datapipeline/templates/demo_skeleton/demo/data/APPL.jsonl +19 -0
  78. datapipeline/templates/demo_skeleton/demo/data/MSFT.jsonl +19 -0
  79. datapipeline/templates/demo_skeleton/demo/dataset.yaml +19 -0
  80. datapipeline/templates/demo_skeleton/demo/postprocess.yaml +19 -0
  81. datapipeline/templates/demo_skeleton/demo/project.yaml +19 -0
  82. datapipeline/templates/demo_skeleton/demo/sources/sandbox.ohlcv.yaml +17 -0
  83. datapipeline/templates/{plugin_skeleton/example → demo_skeleton/demo}/sources/synthetic.ticks.yaml +1 -1
  84. datapipeline/templates/demo_skeleton/demo/tasks/metadata.yaml +2 -0
  85. datapipeline/templates/demo_skeleton/demo/tasks/scaler.yaml +3 -0
  86. datapipeline/templates/demo_skeleton/demo/tasks/schema.yaml +2 -0
  87. datapipeline/templates/demo_skeleton/demo/tasks/serve.test.yaml +4 -0
  88. datapipeline/templates/demo_skeleton/demo/tasks/serve.train.yaml +4 -0
  89. datapipeline/templates/demo_skeleton/demo/tasks/serve.val.yaml +4 -0
  90. datapipeline/templates/demo_skeleton/scripts/run_dataframe.py +20 -0
  91. datapipeline/templates/demo_skeleton/scripts/run_torch.py +23 -0
  92. datapipeline/templates/demo_skeleton/src/{{PACKAGE_NAME}}/__init__.py +0 -0
  93. datapipeline/templates/demo_skeleton/src/{{PACKAGE_NAME}}/domains/equity/__init__.py +0 -0
  94. datapipeline/templates/demo_skeleton/src/{{PACKAGE_NAME}}/domains/equity/model.py +18 -0
  95. datapipeline/templates/demo_skeleton/src/{{PACKAGE_NAME}}/dtos/__init__.py +0 -0
  96. datapipeline/templates/demo_skeleton/src/{{PACKAGE_NAME}}/dtos/sandbox_ohlcv_dto.py +14 -0
  97. datapipeline/templates/demo_skeleton/src/{{PACKAGE_NAME}}/mappers/__init__.py +0 -0
  98. datapipeline/templates/demo_skeleton/src/{{PACKAGE_NAME}}/mappers/map_sandbox_ohlcv_dto_to_equity.py +26 -0
  99. datapipeline/templates/demo_skeleton/src/{{PACKAGE_NAME}}/parsers/__init__.py +0 -0
  100. datapipeline/templates/demo_skeleton/src/{{PACKAGE_NAME}}/parsers/sandbox_ohlcv_dto_parser.py +46 -0
  101. datapipeline/templates/plugin_skeleton/README.md +57 -136
  102. datapipeline/templates/plugin_skeleton/jerry.yaml +12 -24
  103. datapipeline/templates/plugin_skeleton/reference/jerry.yaml +28 -0
  104. datapipeline/templates/plugin_skeleton/reference/reference/contracts/composed.reference.yaml +29 -0
  105. datapipeline/templates/plugin_skeleton/reference/reference/contracts/ingest.reference.yaml +31 -0
  106. datapipeline/templates/plugin_skeleton/reference/reference/contracts/overview.reference.yaml +34 -0
  107. datapipeline/templates/plugin_skeleton/reference/reference/dataset.yaml +29 -0
  108. datapipeline/templates/plugin_skeleton/reference/reference/postprocess.yaml +25 -0
  109. datapipeline/templates/plugin_skeleton/reference/reference/project.yaml +32 -0
  110. datapipeline/templates/plugin_skeleton/reference/reference/sources/foreach.http.reference.yaml +24 -0
  111. datapipeline/templates/plugin_skeleton/reference/reference/sources/foreach.reference.yaml +21 -0
  112. datapipeline/templates/plugin_skeleton/reference/reference/sources/fs.reference.yaml +16 -0
  113. datapipeline/templates/plugin_skeleton/reference/reference/sources/http.reference.yaml +17 -0
  114. datapipeline/templates/plugin_skeleton/reference/reference/sources/overview.reference.yaml +18 -0
  115. datapipeline/templates/plugin_skeleton/reference/reference/sources/synthetic.reference.yaml +15 -0
  116. datapipeline/templates/plugin_skeleton/reference/reference/tasks/metadata.reference.yaml +11 -0
  117. datapipeline/templates/plugin_skeleton/reference/reference/tasks/scaler.reference.yaml +10 -0
  118. datapipeline/templates/plugin_skeleton/reference/reference/tasks/schema.reference.yaml +10 -0
  119. datapipeline/templates/plugin_skeleton/reference/reference/tasks/serve.reference.yaml +28 -0
  120. datapipeline/templates/plugin_skeleton/src/{{PACKAGE_NAME}}/domains/__init__.py +2 -0
  121. datapipeline/templates/plugin_skeleton/src/{{PACKAGE_NAME}}/dtos/__init__.py +0 -0
  122. datapipeline/templates/plugin_skeleton/src/{{PACKAGE_NAME}}/loaders/__init__.py +0 -0
  123. datapipeline/templates/plugin_skeleton/src/{{PACKAGE_NAME}}/mappers/__init__.py +1 -0
  124. datapipeline/templates/plugin_skeleton/src/{{PACKAGE_NAME}}/parsers/__init__.py +0 -0
  125. datapipeline/templates/plugin_skeleton/your-dataset/dataset.yaml +12 -11
  126. datapipeline/templates/plugin_skeleton/your-dataset/postprocess.yaml +4 -13
  127. datapipeline/templates/plugin_skeleton/your-dataset/project.yaml +9 -11
  128. datapipeline/templates/plugin_skeleton/your-dataset/tasks/metadata.yaml +1 -2
  129. datapipeline/templates/plugin_skeleton/your-dataset/tasks/scaler.yaml +1 -7
  130. datapipeline/templates/plugin_skeleton/your-dataset/tasks/schema.yaml +1 -1
  131. datapipeline/templates/plugin_skeleton/your-dataset/tasks/serve.test.yaml +1 -1
  132. datapipeline/templates/plugin_skeleton/your-dataset/tasks/serve.train.yaml +1 -25
  133. datapipeline/templates/plugin_skeleton/your-dataset/tasks/serve.val.yaml +1 -1
  134. datapipeline/templates/plugin_skeleton/your-interim-data-builder/dataset.yaml +9 -0
  135. datapipeline/templates/plugin_skeleton/your-interim-data-builder/postprocess.yaml +1 -0
  136. datapipeline/templates/plugin_skeleton/your-interim-data-builder/project.yaml +15 -0
  137. datapipeline/templates/plugin_skeleton/your-interim-data-builder/tasks/serve.all.yaml +8 -0
  138. datapipeline/templates/stubs/contracts/composed.yaml.j2 +10 -0
  139. datapipeline/templates/stubs/contracts/ingest.yaml.j2 +25 -0
  140. datapipeline/templates/stubs/dto.py.j2 +2 -2
  141. datapipeline/templates/stubs/filter.py.j2 +1 -1
  142. datapipeline/templates/stubs/loaders/basic.py.j2 +11 -0
  143. datapipeline/templates/stubs/mappers/composed.py.j2 +13 -0
  144. datapipeline/templates/stubs/mappers/ingest.py.j2 +20 -0
  145. datapipeline/templates/stubs/parser.py.j2 +5 -1
  146. datapipeline/templates/stubs/record.py.j2 +1 -1
  147. datapipeline/templates/stubs/source.yaml.j2 +1 -1
  148. datapipeline/transforms/debug/identity.py +34 -16
  149. datapipeline/transforms/debug/lint.py +14 -11
  150. datapipeline/transforms/feature/scaler.py +5 -12
  151. datapipeline/transforms/filter.py +73 -17
  152. datapipeline/transforms/interfaces.py +58 -0
  153. datapipeline/transforms/record/floor_time.py +10 -7
  154. datapipeline/transforms/record/lag.py +8 -10
  155. datapipeline/transforms/sequence.py +2 -3
  156. datapipeline/transforms/stream/dedupe.py +5 -7
  157. datapipeline/transforms/stream/ensure_ticks.py +39 -24
  158. datapipeline/transforms/stream/fill.py +34 -25
  159. datapipeline/transforms/stream/filter.py +25 -0
  160. datapipeline/transforms/stream/floor_time.py +16 -0
  161. datapipeline/transforms/stream/granularity.py +52 -30
  162. datapipeline/transforms/stream/lag.py +17 -0
  163. datapipeline/transforms/stream/rolling.py +72 -0
  164. datapipeline/transforms/utils.py +42 -10
  165. datapipeline/transforms/vector/drop/horizontal.py +0 -3
  166. datapipeline/transforms/vector/drop/orchestrator.py +0 -3
  167. datapipeline/transforms/vector/drop/vertical.py +0 -2
  168. datapipeline/transforms/vector/ensure_schema.py +0 -2
  169. datapipeline/utils/paths.py +0 -2
  170. datapipeline/utils/placeholders.py +0 -2
  171. datapipeline/utils/rich_compat.py +0 -3
  172. datapipeline/utils/window.py +0 -2
  173. jerry_thomas-2.0.1.dist-info/METADATA +269 -0
  174. jerry_thomas-2.0.1.dist-info/RECORD +264 -0
  175. {jerry_thomas-1.0.3.dist-info → jerry_thomas-2.0.1.dist-info}/WHEEL +1 -1
  176. {jerry_thomas-1.0.3.dist-info → jerry_thomas-2.0.1.dist-info}/entry_points.txt +7 -3
  177. datapipeline/services/scaffold/mappers.py +0 -55
  178. datapipeline/services/scaffold/source.py +0 -191
  179. datapipeline/templates/plugin_skeleton/example/contracts/time.ticks.hour_sin.yaml +0 -31
  180. datapipeline/templates/plugin_skeleton/example/contracts/time.ticks.linear.yaml +0 -30
  181. datapipeline/templates/plugin_skeleton/example/dataset.yaml +0 -18
  182. datapipeline/templates/plugin_skeleton/example/postprocess.yaml +0 -29
  183. datapipeline/templates/plugin_skeleton/example/project.yaml +0 -23
  184. datapipeline/templates/plugin_skeleton/example/tasks/metadata.yaml +0 -3
  185. datapipeline/templates/plugin_skeleton/example/tasks/scaler.yaml +0 -9
  186. datapipeline/templates/plugin_skeleton/example/tasks/schema.yaml +0 -2
  187. datapipeline/templates/plugin_skeleton/example/tasks/serve.test.yaml +0 -4
  188. datapipeline/templates/plugin_skeleton/example/tasks/serve.train.yaml +0 -28
  189. datapipeline/templates/plugin_skeleton/example/tasks/serve.val.yaml +0 -4
  190. datapipeline/templates/stubs/mapper.py.j2 +0 -22
  191. jerry_thomas-1.0.3.dist-info/METADATA +0 -827
  192. jerry_thomas-1.0.3.dist-info/RECORD +0 -198
  193. {jerry_thomas-1.0.3.dist-info → jerry_thomas-2.0.1.dist-info}/licenses/LICENSE +0 -0
  194. {jerry_thomas-1.0.3.dist-info → jerry_thomas-2.0.1.dist-info}/top_level.txt +0 -0
@@ -1,4 +1,3 @@
1
- from __future__ import annotations
2
1
  from collections import Counter, defaultdict
3
2
  from typing import Any, Hashable, Iterable, Literal
4
3
  from datapipeline.transforms.vector_utils import base_id as _base_id
@@ -1,5 +1,3 @@
1
- from __future__ import annotations
2
-
3
1
  import hashlib
4
2
  from pathlib import Path
5
3
  from typing import Iterable
@@ -1,5 +1,3 @@
1
- from __future__ import annotations
2
-
3
1
  import json
4
2
  from collections import defaultdict
5
3
  from datetime import datetime, timezone
@@ -1,5 +1,3 @@
1
- from __future__ import annotations
2
-
3
1
  from pathlib import Path
4
2
  from typing import Dict, Iterator, Tuple
5
3
 
@@ -1,5 +1,3 @@
1
- from __future__ import annotations
2
-
3
1
  import json
4
2
  from datetime import datetime, timezone
5
3
  from pathlib import Path
@@ -1,5 +1,3 @@
1
- from __future__ import annotations
2
-
3
1
  from collections import Counter, OrderedDict
4
2
  from datetime import datetime
5
3
  from typing import Any
datapipeline/cli/app.py CHANGED
@@ -5,9 +5,15 @@ from typing import Optional, Tuple
5
5
 
6
6
  from datapipeline.cli.commands.run import handle_serve
7
7
  from datapipeline.cli.commands.plugin import bar as handle_bar
8
+ from datapipeline.cli.commands.demo import handle as handle_demo
8
9
  from datapipeline.cli.commands.source import handle as handle_source
9
10
  from datapipeline.cli.commands.domain import handle as handle_domain
10
11
  from datapipeline.cli.commands.contract import handle as handle_contract
12
+ from datapipeline.cli.commands.dto import handle as handle_dto
13
+ from datapipeline.cli.commands.parser import handle as handle_parser
14
+ from datapipeline.cli.commands.mapper import handle as handle_mapper
15
+ from datapipeline.cli.commands.loader import handle as handle_loader
16
+ from datapipeline.cli.commands.stream import handle as handle_stream
11
17
  from datapipeline.cli.commands.list_ import handle as handle_list
12
18
  from datapipeline.cli.commands.filter import handle as handle_filter
13
19
  from datapipeline.cli.commands.inspect import (
@@ -160,9 +166,9 @@ def main() -> None:
160
166
  "--stage",
161
167
  "-s",
162
168
  type=int,
163
- choices=range(0, 8),
169
+ choices=range(0, 9),
164
170
  default=None,
165
- help="preview a specific pipeline stage (0-5 feature stages, 6 assembled vectors, 7 transformed vectors)",
171
+ help="preview a specific pipeline stage (0-6 record/feature stages, 7 assembled vectors, 8 transformed vectors)",
166
172
  )
167
173
  p_serve.add_argument(
168
174
  "--visuals",
@@ -185,7 +191,7 @@ def main() -> None:
185
191
  # build (materialize artifacts)
186
192
  p_build = sub.add_parser(
187
193
  "build",
188
- help="materialize project artifacts (expected ids, hashes, etc.)",
194
+ help="materialize project artifacts (schema, hashes, etc.)",
189
195
  parents=[common],
190
196
  )
191
197
  p_build.add_argument(
@@ -217,22 +223,56 @@ def main() -> None:
217
223
  help="progress display: auto (spinner unless DEBUG), spinner, bars, or off",
218
224
  )
219
225
 
226
+ # demo (optional demo dataset)
227
+ p_demo = sub.add_parser(
228
+ "demo",
229
+ help="create an optional demo dataset inside a plugin",
230
+ parents=[common],
231
+ )
232
+ demo_sub = p_demo.add_subparsers(dest="demo_cmd", required=True)
233
+ demo_init = demo_sub.add_parser(
234
+ "init",
235
+ help="create a standalone demo plugin named demo",
236
+ parents=[common],
237
+ )
238
+ demo_init.add_argument(
239
+ "--out",
240
+ "-o",
241
+ help="override parent directory (demo will be created inside)",
242
+ )
243
+
244
+ # list
245
+ p_list = sub.add_parser(
246
+ "list",
247
+ help="list known resources",
248
+ parents=[common],
249
+ )
250
+ list_sub = p_list.add_subparsers(dest="list_cmd", required=True)
251
+ list_sub.add_parser("sources", help="list sources")
252
+ list_sub.add_parser("domains", help="list domains")
253
+ list_sub.add_parser("parsers", help="list parsers")
254
+ list_sub.add_parser("dtos", help="list DTOs")
255
+ list_sub.add_parser("mappers", help="list mappers")
256
+ list_sub.add_parser("loaders", help="list loaders")
257
+
220
258
  # source
221
259
  p_source = sub.add_parser(
222
260
  "source",
223
- help="add or list raw sources",
261
+ help="create or list raw sources",
224
262
  parents=[common],
225
263
  )
226
264
  source_sub = p_source.add_subparsers(dest="source_cmd", required=True)
227
- p_source_add = source_sub.add_parser(
228
- "add",
229
- help="create a provider+dataset source",
265
+ p_source_create = source_sub.add_parser(
266
+ "create",
267
+ help="create a provider+dataset source (yaml only)",
230
268
  description=(
231
- "Scaffold a source using transport + format.\n\n"
269
+ "Create a source YAML using transport + format or a loader entrypoint.\n\n"
232
270
  "Usage:\n"
233
- " jerry source add <provider> <dataset> -t fs -f csv\n"
234
- " jerry source add <provider>.<dataset> -t http -f json\n"
235
- " jerry source add -p <provider> -d <dataset> -t synthetic\n\n"
271
+ " jerry source create <provider>.<dataset> -t fs -f csv\n"
272
+ " jerry source create <provider>.<dataset> -t http -f json\n"
273
+ " jerry source create <provider>.<dataset> -t synthetic\n\n"
274
+ " jerry source create <provider> <dataset> --loader mypkg.loaders.demo:Loader\n"
275
+ " jerry source create <provider> <dataset> --parser myparser\n\n"
236
276
  "Examples:\n"
237
277
  " fs CSV: -t fs -f csv\n"
238
278
  " fs NDJSON: -t fs -f json-lines\n"
@@ -244,38 +284,47 @@ def main() -> None:
244
284
  # Support simple positionals, plus flags for compatibility
245
285
  # Allow either positionals or flags. Use distinct dest names for flags
246
286
  # to avoid ambiguity when both forms are present in some environments.
247
- p_source_add.add_argument("provider", nargs="?", help="provider name")
248
- p_source_add.add_argument("dataset", nargs="?", help="dataset slug")
249
- p_source_add.add_argument("--provider", "-p", dest="provider_opt", metavar="PROVIDER", help="provider name")
250
- p_source_add.add_argument("--dataset", "-d", dest="dataset_opt", metavar="DATASET", help="dataset slug")
251
- p_source_add.add_argument("--alias", "-a", help="provider.dataset alias")
252
- p_source_add.add_argument(
287
+ for p in (p_source_create,):
288
+ p.add_argument("provider", nargs="?", help="provider name")
289
+ p.add_argument("dataset", nargs="?", help="dataset slug")
290
+ p.add_argument("--provider", "-p", dest="provider_opt", metavar="PROVIDER", help="provider name")
291
+ p.add_argument("--dataset", "-d", dest="dataset_opt", metavar="DATASET", help="dataset slug")
292
+ p.add_argument("--alias", "-a", help="provider.dataset alias")
293
+ p.add_argument(
253
294
  "--transport", "-t",
254
295
  choices=["fs", "http", "synthetic"],
255
- required=True,
296
+ required=False,
256
297
  help="how data is accessed: fs/http/synthetic",
257
- )
258
- p_source_add.add_argument(
259
- "--format", "-f",
260
- choices=["csv", "json", "json-lines", "pickle"],
261
- help="data format for fs/http transports (ignored otherwise)",
262
- )
263
- p_source_add.add_argument(
264
- "--identity",
265
- action="store_true",
266
- help="use the built-in identity parser (skips DTO/parser scaffolding)",
267
- )
298
+ )
299
+ p.add_argument(
300
+ "--format", "-f",
301
+ choices=["csv", "json", "json-lines", "pickle"],
302
+ help="data format for fs/http transports (ignored otherwise)",
303
+ )
304
+ p.add_argument(
305
+ "--loader",
306
+ help="loader entrypoint (overrides --transport/--format)",
307
+ )
308
+ p.add_argument(
309
+ "--parser",
310
+ help="parser entrypoint (defaults to identity)",
311
+ )
312
+ p.add_argument(
313
+ "--identity",
314
+ action="store_true",
315
+ help="use the built-in identity parser (alias for --parser identity)",
316
+ )
268
317
  source_sub.add_parser("list", help="list known sources")
269
318
 
270
319
  # domain
271
320
  p_domain = sub.add_parser(
272
321
  "domain",
273
- help="add or list domains",
322
+ help="create or list domains",
274
323
  parents=[common],
275
324
  )
276
325
  domain_sub = p_domain.add_subparsers(dest="domain_cmd", required=True)
277
326
  p_domain_add = domain_sub.add_parser(
278
- "add",
327
+ "create",
279
328
  help="create a domain",
280
329
  description="Create a time-aware domain package rooted in TemporalRecord.",
281
330
  )
@@ -286,13 +335,64 @@ def main() -> None:
286
335
  )
287
336
  domain_sub.add_parser("list", help="list known domains")
288
337
 
338
+ # dto
339
+ p_dto = sub.add_parser(
340
+ "dto",
341
+ help="create DTOs",
342
+ parents=[common],
343
+ )
344
+ dto_sub = p_dto.add_subparsers(dest="dto_cmd", required=True)
345
+ p_dto_create = dto_sub.add_parser("create", help="create a DTO")
346
+ p_dto_create.add_argument("name", nargs="?", help="DTO class name")
347
+
348
+ # parser
349
+ p_parser = sub.add_parser(
350
+ "parser",
351
+ help="create parsers",
352
+ parents=[common],
353
+ )
354
+ parser_sub = p_parser.add_subparsers(dest="parser_cmd", required=True)
355
+ p_parser_create = parser_sub.add_parser("create", help="create a parser")
356
+ p_parser_create.add_argument("name", nargs="?", help="Parser class name")
357
+
358
+ # mapper
359
+ p_mapper = sub.add_parser(
360
+ "mapper",
361
+ help="create mappers",
362
+ parents=[common],
363
+ )
364
+ mapper_sub = p_mapper.add_subparsers(dest="mapper_cmd", required=True)
365
+ p_mapper_create = mapper_sub.add_parser("create", help="create a mapper")
366
+ p_mapper_create.add_argument("name", nargs="?", help="Mapper function name")
367
+
368
+ # loader
369
+ p_loader = sub.add_parser(
370
+ "loader",
371
+ help="create loaders",
372
+ parents=[common],
373
+ )
374
+ loader_sub = p_loader.add_subparsers(dest="loader_cmd", required=True)
375
+ p_loader_create = loader_sub.add_parser("create", help="create a loader")
376
+ p_loader_create.add_argument("name", nargs="?", help="Loader name")
377
+
378
+ # inflow
379
+ p_inflow = sub.add_parser(
380
+ "inflow",
381
+ help="create end-to-end inflow scaffolds",
382
+ parents=[common],
383
+ )
384
+ inflow_sub = p_inflow.add_subparsers(dest="inflow_cmd", required=True)
385
+ inflow_sub.add_parser("create", help="create an inflow")
386
+
289
387
  # contract (interactive: ingest or composed)
290
388
  p_contract = sub.add_parser(
291
389
  "contract",
292
390
  help="manage stream contracts (ingest or composed)",
293
391
  parents=[common],
294
392
  )
295
- p_contract.add_argument(
393
+ contract_sub = p_contract.add_subparsers(dest="contract_cmd", required=True)
394
+ p_contract_create = contract_sub.add_parser("create", help="create a contract")
395
+ p_contract_create.add_argument(
296
396
  "--identity",
297
397
  action="store_true",
298
398
  help="use built-in identity mapper (skip mapper scaffolding)",
@@ -461,24 +561,6 @@ def main() -> None:
461
561
  help="partitions manifest path (defaults to build/partitions.json)",
462
562
  )
463
563
 
464
- # Expected IDs (newline list)
465
- p_inspect_expected = inspect_sub.add_parser(
466
- "expected",
467
- help="discover full feature ids and write a newline list",
468
- parents=[inspect_common],
469
- )
470
- p_inspect_expected.add_argument(
471
- "--project",
472
- "-p",
473
- default=None,
474
- help="path to project.yaml",
475
- )
476
- p_inspect_expected.add_argument(
477
- "--output",
478
- "-o",
479
- default=None,
480
- help="expected ids output path (defaults to build/datasets/<name>/expected.txt)",
481
- )
482
564
 
483
565
  workspace_context = load_workspace_context(Path.cwd())
484
566
  args = parser.parse_args()
@@ -608,51 +690,82 @@ def main() -> None:
608
690
  log_level=base_level,
609
691
  workspace=workspace_context,
610
692
  )
611
- elif subcmd == "expected":
612
- from datapipeline.cli.commands.inspect import expected as handle_inspect_expected
613
- handle_inspect_expected(
614
- project=args.project,
615
- output=getattr(args, "output", None),
616
- visuals=inspect_visual_provider,
617
- progress=inspect_progress_style,
618
- log_level=base_level,
619
- workspace=workspace_context,
620
- )
621
693
  return
622
694
 
623
695
  if args.cmd == "source":
624
696
  if args.source_cmd == "list":
625
- handle_list(subcmd="sources")
626
- else:
627
- # Merge positionals and flags for provider/dataset
628
- handle_source(
629
- subcmd="add",
630
- provider=(getattr(args, "provider", None) or getattr(args, "provider_opt", None)),
631
- dataset=(getattr(args, "dataset", None) or getattr(args, "dataset_opt", None)),
632
- transport=getattr(args, "transport", None),
633
- format=getattr(args, "format", None),
634
- alias=getattr(args, "alias", None),
635
- identity=getattr(args, "identity", False),
636
- plugin_root=plugin_root,
637
- workspace=workspace_context,
638
- )
697
+ handle_list(subcmd="sources", workspace=workspace_context)
698
+ return
699
+ # Merge positionals and flags for provider/dataset
700
+ handle_source(
701
+ subcmd=args.source_cmd,
702
+ provider=(getattr(args, "provider", None) or getattr(args, "provider_opt", None)),
703
+ dataset=(getattr(args, "dataset", None) or getattr(args, "dataset_opt", None)),
704
+ transport=getattr(args, "transport", None),
705
+ format=getattr(args, "format", None),
706
+ alias=getattr(args, "alias", None),
707
+ identity=getattr(args, "identity", False),
708
+ loader=getattr(args, "loader", None),
709
+ parser=getattr(args, "parser", None),
710
+ plugin_root=plugin_root,
711
+ workspace=workspace_context,
712
+ )
713
+ return
714
+
715
+ if args.cmd == "list":
716
+ handle_list(subcmd=args.list_cmd, workspace=workspace_context)
639
717
  return
640
718
 
641
719
  if args.cmd == "domain":
642
720
  if args.domain_cmd == "list":
643
721
  handle_list(subcmd="domains")
644
- else:
645
- handle_domain(
646
- subcmd="add",
647
- domain=getattr(args, "domain", None),
648
- plugin_root=plugin_root,
649
- )
722
+ return
723
+ handle_domain(
724
+ subcmd=args.domain_cmd,
725
+ domain=getattr(args, "domain", None),
726
+ plugin_root=plugin_root,
727
+ )
728
+ return
729
+
730
+ if args.cmd == "dto":
731
+ handle_dto(
732
+ name=getattr(args, "name", None),
733
+ plugin_root=plugin_root,
734
+ )
735
+ return
736
+
737
+ if args.cmd == "parser":
738
+ handle_parser(
739
+ name=getattr(args, "name", None),
740
+ plugin_root=plugin_root,
741
+ )
742
+ return
743
+
744
+ if args.cmd == "mapper":
745
+ handle_mapper(
746
+ name=getattr(args, "name", None),
747
+ plugin_root=plugin_root,
748
+ )
749
+ return
750
+
751
+ if args.cmd == "loader":
752
+ handle_loader(
753
+ name=getattr(args, "name", None),
754
+ plugin_root=plugin_root,
755
+ )
756
+ return
757
+
758
+ if args.cmd == "inflow":
759
+ handle_stream(
760
+ plugin_root=plugin_root,
761
+ workspace=workspace_context,
762
+ )
650
763
  return
651
764
 
652
765
  if args.cmd == "contract":
653
766
  handle_contract(
654
767
  plugin_root=plugin_root,
655
- use_identity=args.identity,
768
+ use_identity=getattr(args, "identity", False),
656
769
  workspace=workspace_context,
657
770
  )
658
771
  return
@@ -665,6 +778,13 @@ def main() -> None:
665
778
  )
666
779
  return
667
780
 
781
+ if args.cmd == "demo":
782
+ handle_demo(
783
+ subcmd=args.demo_cmd,
784
+ out=getattr(args, "out", None),
785
+ )
786
+ return
787
+
668
788
  if args.cmd == "filter":
669
789
  handle_filter(subcmd=args.filter_cmd, name=getattr(args, "name", None))
670
790
  return