tangle-cli 0.1.3__tar.gz → 0.1.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 (96) hide show
  1. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/PKG-INFO +5 -2
  2. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/README.md +3 -1
  3. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/packages/tangle-cli/src/tangle_cli/__init__.py +1 -1
  4. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/packages/tangle-cli/src/tangle_cli/pipeline_run_manager.py +8 -7
  5. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/packages/tangle-cli/src/tangle_cli/pipeline_runner.py +1 -1
  6. tangle_cli-0.1.4/packages/tangle-cli/src/tangle_cli/pipeline_spec_utils.py +21 -0
  7. tangle_cli-0.1.4/packages/tangle-cli/src/tangle_cli/pipeline_validation.py +593 -0
  8. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/packages/tangle-cli/src/tangle_cli/pipelines.py +29 -212
  9. tangle_cli-0.1.4/packages/tangle-cli/src/tangle_cli/schemas/__init__.py +0 -0
  10. tangle_cli-0.1.4/packages/tangle-cli/src/tangle_cli/schemas/pipeline_schema.json +1949 -0
  11. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/pyproject.toml +2 -1
  12. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/packages/tangle-cli/src/tangle_cli/api_cli.py +0 -0
  13. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/packages/tangle-cli/src/tangle_cli/api_schema.py +0 -0
  14. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/packages/tangle-cli/src/tangle_cli/api_transport.py +0 -0
  15. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/packages/tangle-cli/src/tangle_cli/args_container.py +0 -0
  16. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/packages/tangle-cli/src/tangle_cli/artifacts.py +0 -0
  17. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/packages/tangle-cli/src/tangle_cli/artifacts_cli.py +0 -0
  18. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/packages/tangle-cli/src/tangle_cli/cli.py +0 -0
  19. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/packages/tangle-cli/src/tangle_cli/cli_helpers.py +0 -0
  20. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/packages/tangle-cli/src/tangle_cli/cli_options.py +0 -0
  21. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/packages/tangle-cli/src/tangle_cli/client.py +0 -0
  22. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/packages/tangle-cli/src/tangle_cli/component_from_func.py +0 -0
  23. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/packages/tangle-cli/src/tangle_cli/component_generator.py +0 -0
  24. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/packages/tangle-cli/src/tangle_cli/component_inspector.py +0 -0
  25. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/packages/tangle-cli/src/tangle_cli/component_publisher.py +0 -0
  26. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/packages/tangle-cli/src/tangle_cli/components_cli.py +0 -0
  27. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/packages/tangle-cli/src/tangle_cli/dynamic_discovery_client.py +0 -0
  28. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/packages/tangle-cli/src/tangle_cli/generated_model_extensions.py +0 -0
  29. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/packages/tangle-cli/src/tangle_cli/handler.py +0 -0
  30. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/packages/tangle-cli/src/tangle_cli/hydration_trust.py +0 -0
  31. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/packages/tangle-cli/src/tangle_cli/logger.py +0 -0
  32. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/packages/tangle-cli/src/tangle_cli/models.py +0 -0
  33. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/packages/tangle-cli/src/tangle_cli/module_bundler.py +0 -0
  34. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/packages/tangle-cli/src/tangle_cli/openapi/__init__.py +0 -0
  35. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/packages/tangle-cli/src/tangle_cli/openapi/codegen.py +0 -0
  36. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/packages/tangle-cli/src/tangle_cli/openapi/parser.py +0 -0
  37. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/packages/tangle-cli/src/tangle_cli/pipeline_dehydrator.py +0 -0
  38. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/packages/tangle-cli/src/tangle_cli/pipeline_hydrator.py +0 -0
  39. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/packages/tangle-cli/src/tangle_cli/pipeline_run_annotations.py +0 -0
  40. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/packages/tangle-cli/src/tangle_cli/pipeline_run_details.py +0 -0
  41. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/packages/tangle-cli/src/tangle_cli/pipeline_run_search.py +0 -0
  42. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/packages/tangle-cli/src/tangle_cli/pipeline_runs_cli.py +0 -0
  43. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/packages/tangle-cli/src/tangle_cli/pipelines_cli.py +0 -0
  44. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/packages/tangle-cli/src/tangle_cli/published_components_cli.py +0 -0
  45. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/packages/tangle-cli/src/tangle_cli/py.typed +0 -0
  46. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/packages/tangle-cli/src/tangle_cli/python_pipeline/__init__.py +0 -0
  47. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/packages/tangle-cli/src/tangle_cli/python_pipeline/cfg.py +0 -0
  48. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/packages/tangle-cli/src/tangle_cli/python_pipeline/compiler_context.py +0 -0
  49. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/packages/tangle-cli/src/tangle_cli/python_pipeline/emit.py +0 -0
  50. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/packages/tangle-cli/src/tangle_cli/python_pipeline/errors.py +0 -0
  51. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/packages/tangle-cli/src/tangle_cli/python_pipeline/graph.py +0 -0
  52. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/packages/tangle-cli/src/tangle_cli/python_pipeline/ids.py +0 -0
  53. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/packages/tangle-cli/src/tangle_cli/python_pipeline/pipeline.py +0 -0
  54. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/packages/tangle-cli/src/tangle_cli/python_pipeline/placeholders.py +0 -0
  55. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/packages/tangle-cli/src/tangle_cli/python_pipeline/raw.py +0 -0
  56. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/packages/tangle-cli/src/tangle_cli/python_pipeline/ref.py +0 -0
  57. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/packages/tangle-cli/src/tangle_cli/python_pipeline/registered.py +0 -0
  58. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/packages/tangle-cli/src/tangle_cli/python_pipeline/subpipeline.py +0 -0
  59. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/packages/tangle-cli/src/tangle_cli/python_pipeline/task.py +0 -0
  60. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/packages/tangle-cli/src/tangle_cli/python_pipeline/task_env.py +0 -0
  61. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/packages/tangle-cli/src/tangle_cli/python_pipeline/trace.py +0 -0
  62. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/packages/tangle-cli/src/tangle_cli/python_pipeline/types.py +0 -0
  63. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/packages/tangle-cli/src/tangle_cli/quickstart.py +0 -0
  64. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/packages/tangle-cli/src/tangle_cli/secrets.py +0 -0
  65. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/packages/tangle-cli/src/tangle_cli/secrets_cli.py +0 -0
  66. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/packages/tangle-cli/src/tangle_cli/utils.py +0 -0
  67. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/packages/tangle-cli/src/tangle_cli/version_manager.py +0 -0
  68. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/skills/tangent/OSS-CONVENTIONS.md +0 -0
  69. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/skills/tangent/PORT-README.md +0 -0
  70. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/skills/tangent/SKILL.md +0 -0
  71. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/skills/tangent/agents/auth-wizard.md +0 -0
  72. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/skills/tangent/agents/builder.md +0 -0
  73. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/skills/tangent/agents/debugger.md +0 -0
  74. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/skills/tangent/agents/reporter.md +0 -0
  75. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/skills/tangent/agents/researcher.md +0 -0
  76. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/skills/tangent/agents/reviewer.md +0 -0
  77. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/skills/tangent/agents/scenario-builder.md +0 -0
  78. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/skills/tangent/references/data-sources.md +0 -0
  79. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/skills/tangent/references/event-log.md +0 -0
  80. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/skills/tangent/references/example-scenarios/01-mslr-ranking.md +0 -0
  81. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/skills/tangent/references/example-scenarios/02-text-classification.md +0 -0
  82. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/skills/tangent/references/example-scenarios/INDEX.md +0 -0
  83. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/skills/tangent/references/iterating-on-runs.md +0 -0
  84. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/skills/tangent/references/knowledge-corpus.md +0 -0
  85. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/skills/tangent/references/secrets.md +0 -0
  86. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/skills/tangent/references/setup.md +0 -0
  87. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/skills/tangent/references/step-0-initialize.md +0 -0
  88. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/skills/tangent/references/step-1-analyze.md +0 -0
  89. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/skills/tangent/references/step-2-hypothesize.md +0 -0
  90. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/skills/tangent/references/step-3-submit.md +0 -0
  91. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/skills/tangent/references/step-4-monitor.md +0 -0
  92. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/skills/tangent/references/step-5-evaluate.md +0 -0
  93. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/skills/tangent/references/step-6-synthesize.md +0 -0
  94. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/skills/tangent/references/step-7-decide.md +0 -0
  95. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/skills/tangent/references/tangle-tools.md +0 -0
  96. {tangle_cli-0.1.3 → tangle_cli-0.1.4}/skills/tangent/references/uploading-artifacts.md +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: tangle-cli
3
- Version: 0.1.3
3
+ Version: 0.1.4
4
4
  Summary: CLI for Tangle, the open-source ML pipeline orchestration platform
5
5
  Author: Alexey Volkov, Tangle authors, Volv Grebennikov
6
6
  Author-email: Alexey Volkov <alexey.volkov@ark-kun.com>, Volv Grebennikov <volv.grebennikov@shopify.com>
@@ -9,6 +9,7 @@ Requires-Dist: cyclopts>=4.16.1
9
9
  Requires-Dist: docstring-parser>=0.16
10
10
  Requires-Dist: httpx>=0.28.1
11
11
  Requires-Dist: jinja2>=3.1
12
+ Requires-Dist: jsonschema>=4.25.0
12
13
  Requires-Dist: platformdirs>=4.10.0
13
14
  Requires-Dist: pydantic>=2.0
14
15
  Requires-Dist: pyyaml>=6.0
@@ -316,9 +317,11 @@ uv run tangle sdk pipeline-runs annotations set RUN_ID key value
316
317
  uv run tangle sdk pipeline-runs export RUN_ID --output pipeline.yaml
317
318
  ```
318
319
 
320
+ `pipelines validate` checks local graph shape, the packaged Tangle pipeline JSON schema, and component input wiring when component specs are present. It does not hydrate refs; validate a hydrated file when you need fully resolved component-input checks for remote refs.
321
+
319
322
  `submit` hydrates refs by default and builds an API submit payload with `root_task.componentRef.spec`. Use `--no-hydrate` to submit the local YAML structure as-is. Use `--dry-run` to print the payload without creating a run.
320
323
 
321
- Before creating a run—or printing a `--dry-run` payload—`submit` runs the same authoring validation as `tangle sdk pipelines validate` on the hydrated/resolved pipeline spec (or on the as-is spec when `--no-hydrate` is used). Invalid specs fail locally with `Pipeline validation failed` errors before the run-submission API call. For example, the pipeline root must be a graph (`implementation.graph`), so a bare `implementation.container` root is rejected before the run is submitted.
324
+ Before creating a run—or printing a `--dry-run` payload—`submit` runs the same authoring validation as `tangle sdk pipelines validate` on the hydrated/resolved pipeline spec (or on the as-is spec when `--no-hydrate` is used). Invalid specs fail locally with `Pipeline validation failed` errors before the run-submission API call. For example, the pipeline root must be a graph (`implementation.graph`), so a bare `implementation.container` root is rejected before the run is submitted; missing required component inputs and invalid task output references are rejected when component specs are available.
322
325
 
323
326
  ## Programmatic client
324
327
 
@@ -291,9 +291,11 @@ uv run tangle sdk pipeline-runs annotations set RUN_ID key value
291
291
  uv run tangle sdk pipeline-runs export RUN_ID --output pipeline.yaml
292
292
  ```
293
293
 
294
+ `pipelines validate` checks local graph shape, the packaged Tangle pipeline JSON schema, and component input wiring when component specs are present. It does not hydrate refs; validate a hydrated file when you need fully resolved component-input checks for remote refs.
295
+
294
296
  `submit` hydrates refs by default and builds an API submit payload with `root_task.componentRef.spec`. Use `--no-hydrate` to submit the local YAML structure as-is. Use `--dry-run` to print the payload without creating a run.
295
297
 
296
- Before creating a run—or printing a `--dry-run` payload—`submit` runs the same authoring validation as `tangle sdk pipelines validate` on the hydrated/resolved pipeline spec (or on the as-is spec when `--no-hydrate` is used). Invalid specs fail locally with `Pipeline validation failed` errors before the run-submission API call. For example, the pipeline root must be a graph (`implementation.graph`), so a bare `implementation.container` root is rejected before the run is submitted.
298
+ Before creating a run—or printing a `--dry-run` payload—`submit` runs the same authoring validation as `tangle sdk pipelines validate` on the hydrated/resolved pipeline spec (or on the as-is spec when `--no-hydrate` is used). Invalid specs fail locally with `Pipeline validation failed` errors before the run-submission API call. For example, the pipeline root must be a graph (`implementation.graph`), so a bare `implementation.container` root is rejected before the run is submitted; missing required component inputs and invalid task output references are rejected when component specs are available.
297
299
 
298
300
  ## Programmatic client
299
301
 
@@ -14,6 +14,6 @@ from tangle_cli.dynamic_discovery_client import TangleDynamicDiscoveryClient
14
14
  try:
15
15
  __version__ = metadata_version("tangle-cli")
16
16
  except PackageNotFoundError:
17
- __version__ = "0.1.3"
17
+ __version__ = "0.1.4"
18
18
 
19
19
  __all__ = ["TangleDynamicDiscoveryClient", "__version__"]
@@ -954,13 +954,14 @@ class PipelineRunManager(TangleCliHandler):
954
954
  )
955
955
  prepared_run_args = self.hooks.prepare_run_arguments(prepared_spec, run_args)
956
956
  prepared_spec = self.apply_run_name_template(prepared_spec, prepared_run_args)
957
- validation_errors = self.hooks.validate_pipeline_for_run(
958
- prepared_spec,
959
- pipeline_path=pipeline_path,
960
- effective_path=None,
961
- skip_validation=skip_validation,
962
- )
963
- self._raise_pipeline_validation_error(validation_errors)
957
+ if not skip_validation:
958
+ validation_errors = self.hooks.validate_pipeline_for_run(
959
+ prepared_spec,
960
+ pipeline_path=pipeline_path,
961
+ effective_path=None,
962
+ skip_validation=False,
963
+ )
964
+ self._raise_pipeline_validation_error(validation_errors)
964
965
  payload = self.convert_yaml_to_payload(copy.deepcopy(prepared_spec), prepared_run_args)
965
966
  payload = self.sanitize_submit_payload(payload)
966
967
  root_task = payload["root_task"]
@@ -529,7 +529,7 @@ class PipelineRunner(PipelineRunnerHooks, PipelineRunManager):
529
529
  pipeline_path=pipeline_path,
530
530
  run_as=run_as,
531
531
  hydrate=False,
532
- skip_validation=skip_validation,
532
+ skip_validation=True,
533
533
  )
534
534
  submit_payloads[attempt] = submit_payload
535
535
  return submit_payload.to_body()
@@ -0,0 +1,21 @@
1
+ """Shared helpers for traversing Tangle pipeline spec dictionaries."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any, Mapping
6
+
7
+
8
+ def _extract_task_output_refs(value: Any) -> set[str]:
9
+ """Return task ids referenced by nested taskOutput argument values."""
10
+
11
+ refs: set[str] = set()
12
+ if isinstance(value, Mapping):
13
+ task_output = value.get("taskOutput")
14
+ if isinstance(task_output, Mapping) and isinstance(task_output.get("taskId"), str):
15
+ refs.add(task_output["taskId"])
16
+ for nested in value.values():
17
+ refs.update(_extract_task_output_refs(nested))
18
+ elif isinstance(value, list):
19
+ for item in value:
20
+ refs.update(_extract_task_output_refs(item))
21
+ return refs