tangle-cli 0.1.10__tar.gz → 0.1.12__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.
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/PKG-INFO +107 -3
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/README.md +106 -2
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/packages/tangle-cli/src/tangle_cli/__init__.py +1 -1
- tangle_cli-0.1.12/packages/tangle-cli/src/tangle_cli/args_container.py +518 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/packages/tangle-cli/src/tangle_cli/cli_helpers.py +33 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/packages/tangle-cli/src/tangle_cli/pipeline_runs_cli.py +411 -1
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/packages/tangle-cli/src/tangle_cli/pipelines_cli.py +9 -27
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/pyproject.toml +1 -1
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/pyproject.toml.orig +1 -1
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/skills/tangent/OSS-CONVENTIONS.md +2 -1
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/skills/tangent/references/tangle-tools.md +24 -1
- tangle_cli-0.1.10/packages/tangle-cli/src/tangle_cli/args_container.py +0 -244
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/packages/tangle-cli/src/tangle_cli/api_cli.py +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/packages/tangle-cli/src/tangle_cli/api_schema.py +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/packages/tangle-cli/src/tangle_cli/api_transport.py +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/packages/tangle-cli/src/tangle_cli/artifacts.py +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/packages/tangle-cli/src/tangle_cli/artifacts_cli.py +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/packages/tangle-cli/src/tangle_cli/cli.py +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/packages/tangle-cli/src/tangle_cli/cli_options.py +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/packages/tangle-cli/src/tangle_cli/client.py +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/packages/tangle-cli/src/tangle_cli/component_from_func.py +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/packages/tangle-cli/src/tangle_cli/component_generator.py +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/packages/tangle-cli/src/tangle_cli/component_inspector.py +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/packages/tangle-cli/src/tangle_cli/component_publisher.py +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/packages/tangle-cli/src/tangle_cli/components_cli.py +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/packages/tangle-cli/src/tangle_cli/dynamic_discovery_client.py +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/packages/tangle-cli/src/tangle_cli/generated_model_extensions.py +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/packages/tangle-cli/src/tangle_cli/handler.py +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/packages/tangle-cli/src/tangle_cli/hydration_trust.py +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/packages/tangle-cli/src/tangle_cli/logger.py +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/packages/tangle-cli/src/tangle_cli/models.py +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/packages/tangle-cli/src/tangle_cli/module_bundler.py +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/packages/tangle-cli/src/tangle_cli/openapi/__init__.py +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/packages/tangle-cli/src/tangle_cli/openapi/codegen.py +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/packages/tangle-cli/src/tangle_cli/openapi/parser.py +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/packages/tangle-cli/src/tangle_cli/pipeline_compiler.py +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/packages/tangle-cli/src/tangle_cli/pipeline_dehydrator.py +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/packages/tangle-cli/src/tangle_cli/pipeline_hydrator.py +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/packages/tangle-cli/src/tangle_cli/pipeline_run_annotations.py +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/packages/tangle-cli/src/tangle_cli/pipeline_run_details.py +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/packages/tangle-cli/src/tangle_cli/pipeline_run_manager.py +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/packages/tangle-cli/src/tangle_cli/pipeline_run_search.py +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/packages/tangle-cli/src/tangle_cli/pipeline_runner.py +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/packages/tangle-cli/src/tangle_cli/pipeline_spec_utils.py +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/packages/tangle-cli/src/tangle_cli/pipeline_validation.py +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/packages/tangle-cli/src/tangle_cli/pipelines.py +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/packages/tangle-cli/src/tangle_cli/published_components_cli.py +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/packages/tangle-cli/src/tangle_cli/py.typed +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/packages/tangle-cli/src/tangle_cli/python_pipeline/__init__.py +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/packages/tangle-cli/src/tangle_cli/python_pipeline/cfg.py +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/packages/tangle-cli/src/tangle_cli/python_pipeline/compiler_context.py +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/packages/tangle-cli/src/tangle_cli/python_pipeline/dynamic_data.py +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/packages/tangle-cli/src/tangle_cli/python_pipeline/emit.py +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/packages/tangle-cli/src/tangle_cli/python_pipeline/errors.py +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/packages/tangle-cli/src/tangle_cli/python_pipeline/graph.py +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/packages/tangle-cli/src/tangle_cli/python_pipeline/ids.py +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/packages/tangle-cli/src/tangle_cli/python_pipeline/pipeline.py +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/packages/tangle-cli/src/tangle_cli/python_pipeline/placeholders.py +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/packages/tangle-cli/src/tangle_cli/python_pipeline/raw.py +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/packages/tangle-cli/src/tangle_cli/python_pipeline/ref.py +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/packages/tangle-cli/src/tangle_cli/python_pipeline/registered.py +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/packages/tangle-cli/src/tangle_cli/python_pipeline/subpipeline.py +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/packages/tangle-cli/src/tangle_cli/python_pipeline/task.py +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/packages/tangle-cli/src/tangle_cli/python_pipeline/task_env.py +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/packages/tangle-cli/src/tangle_cli/python_pipeline/trace.py +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/packages/tangle-cli/src/tangle_cli/python_pipeline/types.py +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/packages/tangle-cli/src/tangle_cli/quickstart.py +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/packages/tangle-cli/src/tangle_cli/schema_validation.py +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/packages/tangle-cli/src/tangle_cli/schemas/__init__.py +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/packages/tangle-cli/src/tangle_cli/schemas/dehydrated_pipeline_schema.json +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/packages/tangle-cli/src/tangle_cli/schemas/pipeline_schema.json +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/packages/tangle-cli/src/tangle_cli/secrets.py +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/packages/tangle-cli/src/tangle_cli/secrets_cli.py +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/packages/tangle-cli/src/tangle_cli/utils.py +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/packages/tangle-cli/src/tangle_cli/version_manager.py +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/skills/tangent/PORT-README.md +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/skills/tangent/SKILL.md +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/skills/tangent/agents/auth-wizard.md +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/skills/tangent/agents/builder.md +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/skills/tangent/agents/debugger.md +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/skills/tangent/agents/reporter.md +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/skills/tangent/agents/researcher.md +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/skills/tangent/agents/reviewer.md +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/skills/tangent/agents/scenario-builder.md +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/skills/tangent/references/data-sources.md +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/skills/tangent/references/event-log.md +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/skills/tangent/references/example-scenarios/01-mslr-ranking.md +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/skills/tangent/references/example-scenarios/02-text-classification.md +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/skills/tangent/references/example-scenarios/INDEX.md +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/skills/tangent/references/iterating-on-runs.md +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/skills/tangent/references/knowledge-corpus.md +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/skills/tangent/references/secrets.md +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/skills/tangent/references/setup.md +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/skills/tangent/references/step-0-initialize.md +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/skills/tangent/references/step-1-analyze.md +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/skills/tangent/references/step-2-hypothesize.md +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/skills/tangent/references/step-3-submit.md +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/skills/tangent/references/step-4-monitor.md +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/skills/tangent/references/step-5-evaluate.md +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/skills/tangent/references/step-6-synthesize.md +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/skills/tangent/references/step-7-decide.md +0 -0
- {tangle_cli-0.1.10 → tangle_cli-0.1.12}/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
|
+
Version: 0.1.12
|
|
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>
|
|
@@ -83,7 +83,7 @@ API-backed commands commonly accept these options. Explicit CLI options win over
|
|
|
83
83
|
| `--token`, `TANGLE_API_TOKEN` | Bearer token shorthand. |
|
|
84
84
|
| `--auth-header`, `TANGLE_API_AUTH_HEADER`, `TANGLE_AUTH_HEADER` | Full `Authorization` value such as `Bearer ...` or `Basic ...`. |
|
|
85
85
|
| `-H`, `--header`, `TANGLE_API_HEADERS` | Extra headers. Repeatable as CLI flags; env accepts a JSON object or newline-separated `Name: value` entries. |
|
|
86
|
-
| `--config` | YAML/JSON defaults. Many commands accept a single object, a list of objects, or `_defaults` + `configs
|
|
86
|
+
| `--config` | YAML/JSON defaults. Many commands accept a single object, a list of objects, or `_defaults` + `configs`, optionally wrapped in a top-level `_select` environment selector. |
|
|
87
87
|
| `--log-type` | SDK progress logs: `console`, `none`, or `file`. Logs go to stderr or a temp log file so structured stdout stays parseable. |
|
|
88
88
|
| `TANGLE_VERBOSE=1` | Redacted HTTP request/response diagnostics only. This is separate from normal progress logging. |
|
|
89
89
|
| `--ca-bundle` | Global CLI flag: path to a PEM CA bundle used as the TLS trust store for every transport. Overrides `TANGLE_API_CA_BUNDLE`. Place before the subcommand. |
|
|
@@ -256,6 +256,56 @@ uv run tangle sdk pipeline-runs submit --config submit.yaml
|
|
|
256
256
|
|
|
257
257
|
For generated `tangle api` commands, config keys use generated CLI parameter names such as `base_url`, `schema_source`, `body`, and endpoint parameters like `limit`, `filter`, or `id`.
|
|
258
258
|
|
|
259
|
+
### Environment-selected configs (`_select`)
|
|
260
|
+
|
|
261
|
+
Any command that accepts `--config` can pick one of several config documents from an environment variable by making `_select` the top-level node:
|
|
262
|
+
|
|
263
|
+
```yaml
|
|
264
|
+
_shared: &shared
|
|
265
|
+
log_type: none
|
|
266
|
+
|
|
267
|
+
_select:
|
|
268
|
+
env: TANGLE_ENV
|
|
269
|
+
cases:
|
|
270
|
+
dev:
|
|
271
|
+
<<: *shared
|
|
272
|
+
base_url: https://api.dev
|
|
273
|
+
prod:
|
|
274
|
+
_defaults:
|
|
275
|
+
<<: *shared
|
|
276
|
+
base_url: https://api.prod
|
|
277
|
+
configs:
|
|
278
|
+
- filter: active
|
|
279
|
+
- filter: finished
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
The selected branch is a complete config document — a single object, a list of objects, or `_defaults` + `configs` — and is then loaded exactly as if it had been written on its own. A branch may itself be another `_select` node, which composes multiple dimensions (for example environment and region).
|
|
283
|
+
|
|
284
|
+
Selection fails closed by default. To opt into a fallback, author an explicit `default` branch:
|
|
285
|
+
|
|
286
|
+
```yaml
|
|
287
|
+
_select:
|
|
288
|
+
env: TANGLE_ENV
|
|
289
|
+
cases:
|
|
290
|
+
prod:
|
|
291
|
+
base_url: https://api.prod
|
|
292
|
+
default:
|
|
293
|
+
base_url: https://api.dev
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
With `default`, an unset variable or a value matching no case resolves to that branch; an exact case match always wins over it. Without `default`, both remain errors. `default` is a sibling of `cases`, not an entry inside it: a case *named* `default` stays an ordinary exact-match case. Like any branch, `default` must be a complete valid config shape and may itself be another `_select`; an inner selector does not inherit the outer `default`.
|
|
297
|
+
|
|
298
|
+
Rules:
|
|
299
|
+
|
|
300
|
+
- `_select` is the only newly reserved key, and it is an exact key name rather than a prefix. Configs without `_select` are unchanged byte-for-byte and semantically.
|
|
301
|
+
- At a `_select` node, only `_select` and other underscore-prefixed helper keys (YAML anchor holders such as `_shared`) may appear; ordinary sibling keys are rejected.
|
|
302
|
+
- `_select` accepts only `env`, `cases`, and the optional `default`. There are no aliases: `else`, `fallback`, and `defaults` are rejected.
|
|
303
|
+
- The selector shape, the `env` name, every `cases` key, and every case and `default` branch are validated before the environment is read, so a malformed selector fails identically in every environment. Branches are checked as complete config documents with the same rules the loader applies to a whole file, and nested selectors are validated recursively.
|
|
304
|
+
- Only environment *lookups* are lazy. A dormant branch is fully shape-checked, but its `env` variable is never required unless that branch is actually selected. Command-specific field names and types are still validated later, against the selected branch only.
|
|
305
|
+
- Selector nesting is capped at 32 levels, which also stops a self-referential YAML alias. A node shared by several anchors is validated once, so anchor-heavy files stay fast.
|
|
306
|
+
- Matching uses `os.environ[NAME]` exactly: case sensitive, with no trimming, case folding, or interpolation.
|
|
307
|
+
- Fallback exists only where it is authored. Without `default`, an unset variable or an unmatched value is an error; there is never an implicit default or implicit production branch. The raw environment value is never echoed — diagnostics list only the configured case names.
|
|
308
|
+
|
|
259
309
|
## API schema cache and dynamic commands
|
|
260
310
|
|
|
261
311
|
Refresh the local schema cache for a live backend with:
|
|
@@ -331,7 +381,7 @@ uv run tangle sdk published-components deprecate sha256:old --superseded-by sha2
|
|
|
331
381
|
|
|
332
382
|
`publish` accepts `--image`, `--name`, `--description`, `--annotations` (JSON), `--dry-run`, `--published-by`, generic git metadata fields, generic API auth fields, `--log-type`, and `--config`. By default it scopes version checks and automatic old-version deprecation to the current authenticated user via `users_me()`; use `--published-by` to supply an explicit owner/publisher filter. Publishing fails closed if no owner can be determined.
|
|
333
383
|
|
|
334
|
-
There is no separate OSS `publish-all` command. To publish multiple components, pass a YAML/JSON config list, or `_defaults` + `configs`, to the same `published-components publish` command; the command aggregates results and exits nonzero if any component errors.
|
|
384
|
+
There is no separate OSS `publish-all` command. To publish multiple components, pass a YAML/JSON config list, or `_defaults` + `configs`, to the same `published-components publish` command; the command aggregates results and exits nonzero if any component errors. A top-level `_select` node can choose between such documents per environment (see [Environment-selected configs](#environment-selected-configs-_select)).
|
|
335
385
|
|
|
336
386
|
```yaml
|
|
337
387
|
_defaults:
|
|
@@ -362,6 +412,7 @@ Pipeline run API/submit commands live under `sdk pipeline-runs`:
|
|
|
362
412
|
```bash
|
|
363
413
|
uv run tangle sdk pipeline-runs submit pipeline.yaml --dry-run
|
|
364
414
|
uv run tangle sdk pipeline-runs submit pipeline.yaml --arg key=value --annotation owner=team
|
|
415
|
+
uv run tangle sdk pipeline-runs submit-from-python pipeline.py --arg key=value
|
|
365
416
|
uv run tangle sdk pipeline-runs wait RUN_ID --max-wait 600 --poll-interval 10
|
|
366
417
|
uv run tangle sdk pipeline-runs logs EXECUTION_ID
|
|
367
418
|
uv run tangle sdk pipeline-runs annotations set RUN_ID key value
|
|
@@ -377,6 +428,59 @@ uv run tangle sdk pipelines compile pipeline.py -o pipeline.yaml
|
|
|
377
428
|
uv run tangle sdk pipelines compile pipeline.py -o pipeline.yaml --pipeline pipeline_fn_name
|
|
378
429
|
```
|
|
379
430
|
|
|
431
|
+
To compile and submit in one step, without keeping the compiled YAML around, use
|
|
432
|
+
`pipeline-runs submit-from-python`:
|
|
433
|
+
|
|
434
|
+
```bash
|
|
435
|
+
uv run tangle sdk pipeline-runs submit-from-python pipeline.py \
|
|
436
|
+
--override batch_size=100 \
|
|
437
|
+
--image eval-slim=registry.example/eval-slim@sha256:... \
|
|
438
|
+
--arg shop=acme --annotation owner=team
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
It compiles the script, hydrates the bundle, submits the run, and removes the
|
|
442
|
+
compiled artifacts again — including on dry runs and failures. Its run-tier
|
|
443
|
+
flags are the same as `pipeline-runs submit`; the extra compile-tier flags are
|
|
444
|
+
`--pipeline`, repeatable `--override KEY=VALUE`, and repeatable `--image ID=REF`.
|
|
445
|
+
Use `pipelines compile` instead when the compiled YAML itself is what you want.
|
|
446
|
+
|
|
447
|
+
The two value tiers are distinct and easy to confuse:
|
|
448
|
+
|
|
449
|
+
| Flag | Tier | Meaning |
|
|
450
|
+
| --- | --- | --- |
|
|
451
|
+
| `--override KEY=VALUE` | compile | `cfg` value used while the graph is built |
|
|
452
|
+
| `--image ID=REF` | compile | resolves `@task(image_id=ID)` to a registry ref |
|
|
453
|
+
| `--arg` / `--args-json` / `--arg-secret` | run | pipeline arguments for the created run |
|
|
454
|
+
|
|
455
|
+
Notes:
|
|
456
|
+
|
|
457
|
+
- Hydration is always on: the compiled bundle references local sidecars
|
|
458
|
+
(`resolve://./<stem>.components.yaml#…`, `file://<stem>.subgraphs/…`) that the
|
|
459
|
+
server cannot read. There is no `--no-hydrate` here.
|
|
460
|
+
- The bundle is compiled next to the script (never in `/tmp`) under a unique
|
|
461
|
+
hidden `.tangle-submit-*.yaml` name, because relative refs such as
|
|
462
|
+
`ref(url="file://./component.yaml")` resolve against the *output* directory.
|
|
463
|
+
The name is allocated with an exclusive create, so concurrent compiles of the
|
|
464
|
+
same script never collide or overwrite a sibling YAML. A symlinked script
|
|
465
|
+
compiles next to its resolved target, where its `config.yaml` and relative
|
|
466
|
+
refs actually live.
|
|
467
|
+
- The bundle stays readable until every run has been submitted, so
|
|
468
|
+
run-lifecycle hooks still see an existing `pipeline_path`; cleanup then
|
|
469
|
+
removes exactly that stem's files (`.yaml`, `.components.yaml`,
|
|
470
|
+
`.subgraphs/`) and nothing else.
|
|
471
|
+
- Submission never waits; use `pipeline-runs wait RUN_ID`.
|
|
472
|
+
- With a multi-entry `--config` file, entries may carry different `--override` /
|
|
473
|
+
`--image` values, and **every entry is fully prepared before any run is
|
|
474
|
+
created**: each is compiled exactly once, hydrated, merged with its run
|
|
475
|
+
arguments and secrets, validated, and frozen into a submit body; only then are
|
|
476
|
+
the frozen bodies submitted in order (no recompilation). An unsupported config
|
|
477
|
+
key (`hydrate:`, `pipeline_path:`), a malformed `override` / `image` /
|
|
478
|
+
`arg-secret` value, an input given as both `--arg` and `--arg-secret`, a
|
|
479
|
+
missing script, or a compile/hydrate error in *any* entry therefore creates no
|
|
480
|
+
runs and leaves no artifacts behind. A runtime failure while submitting entry
|
|
481
|
+
N can still follow the successful submits of entries 1..N-1 — that is inherent
|
|
482
|
+
to creating N runs.
|
|
483
|
+
|
|
380
484
|
A minimal graph uses `@pipeline` for the graph and `@task` for local Python components. `@task` functions are not executed at compile time; the compiler records call sites, emits a sibling `<output>.components.yaml` with `local_from_python` entries, and rewrites task component refs to that sidecar. Hydrate later regenerates the same component YAML from the Python source.
|
|
381
485
|
|
|
382
486
|
```python
|
|
@@ -57,7 +57,7 @@ API-backed commands commonly accept these options. Explicit CLI options win over
|
|
|
57
57
|
| `--token`, `TANGLE_API_TOKEN` | Bearer token shorthand. |
|
|
58
58
|
| `--auth-header`, `TANGLE_API_AUTH_HEADER`, `TANGLE_AUTH_HEADER` | Full `Authorization` value such as `Bearer ...` or `Basic ...`. |
|
|
59
59
|
| `-H`, `--header`, `TANGLE_API_HEADERS` | Extra headers. Repeatable as CLI flags; env accepts a JSON object or newline-separated `Name: value` entries. |
|
|
60
|
-
| `--config` | YAML/JSON defaults. Many commands accept a single object, a list of objects, or `_defaults` + `configs
|
|
60
|
+
| `--config` | YAML/JSON defaults. Many commands accept a single object, a list of objects, or `_defaults` + `configs`, optionally wrapped in a top-level `_select` environment selector. |
|
|
61
61
|
| `--log-type` | SDK progress logs: `console`, `none`, or `file`. Logs go to stderr or a temp log file so structured stdout stays parseable. |
|
|
62
62
|
| `TANGLE_VERBOSE=1` | Redacted HTTP request/response diagnostics only. This is separate from normal progress logging. |
|
|
63
63
|
| `--ca-bundle` | Global CLI flag: path to a PEM CA bundle used as the TLS trust store for every transport. Overrides `TANGLE_API_CA_BUNDLE`. Place before the subcommand. |
|
|
@@ -230,6 +230,56 @@ uv run tangle sdk pipeline-runs submit --config submit.yaml
|
|
|
230
230
|
|
|
231
231
|
For generated `tangle api` commands, config keys use generated CLI parameter names such as `base_url`, `schema_source`, `body`, and endpoint parameters like `limit`, `filter`, or `id`.
|
|
232
232
|
|
|
233
|
+
### Environment-selected configs (`_select`)
|
|
234
|
+
|
|
235
|
+
Any command that accepts `--config` can pick one of several config documents from an environment variable by making `_select` the top-level node:
|
|
236
|
+
|
|
237
|
+
```yaml
|
|
238
|
+
_shared: &shared
|
|
239
|
+
log_type: none
|
|
240
|
+
|
|
241
|
+
_select:
|
|
242
|
+
env: TANGLE_ENV
|
|
243
|
+
cases:
|
|
244
|
+
dev:
|
|
245
|
+
<<: *shared
|
|
246
|
+
base_url: https://api.dev
|
|
247
|
+
prod:
|
|
248
|
+
_defaults:
|
|
249
|
+
<<: *shared
|
|
250
|
+
base_url: https://api.prod
|
|
251
|
+
configs:
|
|
252
|
+
- filter: active
|
|
253
|
+
- filter: finished
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
The selected branch is a complete config document — a single object, a list of objects, or `_defaults` + `configs` — and is then loaded exactly as if it had been written on its own. A branch may itself be another `_select` node, which composes multiple dimensions (for example environment and region).
|
|
257
|
+
|
|
258
|
+
Selection fails closed by default. To opt into a fallback, author an explicit `default` branch:
|
|
259
|
+
|
|
260
|
+
```yaml
|
|
261
|
+
_select:
|
|
262
|
+
env: TANGLE_ENV
|
|
263
|
+
cases:
|
|
264
|
+
prod:
|
|
265
|
+
base_url: https://api.prod
|
|
266
|
+
default:
|
|
267
|
+
base_url: https://api.dev
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
With `default`, an unset variable or a value matching no case resolves to that branch; an exact case match always wins over it. Without `default`, both remain errors. `default` is a sibling of `cases`, not an entry inside it: a case *named* `default` stays an ordinary exact-match case. Like any branch, `default` must be a complete valid config shape and may itself be another `_select`; an inner selector does not inherit the outer `default`.
|
|
271
|
+
|
|
272
|
+
Rules:
|
|
273
|
+
|
|
274
|
+
- `_select` is the only newly reserved key, and it is an exact key name rather than a prefix. Configs without `_select` are unchanged byte-for-byte and semantically.
|
|
275
|
+
- At a `_select` node, only `_select` and other underscore-prefixed helper keys (YAML anchor holders such as `_shared`) may appear; ordinary sibling keys are rejected.
|
|
276
|
+
- `_select` accepts only `env`, `cases`, and the optional `default`. There are no aliases: `else`, `fallback`, and `defaults` are rejected.
|
|
277
|
+
- The selector shape, the `env` name, every `cases` key, and every case and `default` branch are validated before the environment is read, so a malformed selector fails identically in every environment. Branches are checked as complete config documents with the same rules the loader applies to a whole file, and nested selectors are validated recursively.
|
|
278
|
+
- Only environment *lookups* are lazy. A dormant branch is fully shape-checked, but its `env` variable is never required unless that branch is actually selected. Command-specific field names and types are still validated later, against the selected branch only.
|
|
279
|
+
- Selector nesting is capped at 32 levels, which also stops a self-referential YAML alias. A node shared by several anchors is validated once, so anchor-heavy files stay fast.
|
|
280
|
+
- Matching uses `os.environ[NAME]` exactly: case sensitive, with no trimming, case folding, or interpolation.
|
|
281
|
+
- Fallback exists only where it is authored. Without `default`, an unset variable or an unmatched value is an error; there is never an implicit default or implicit production branch. The raw environment value is never echoed — diagnostics list only the configured case names.
|
|
282
|
+
|
|
233
283
|
## API schema cache and dynamic commands
|
|
234
284
|
|
|
235
285
|
Refresh the local schema cache for a live backend with:
|
|
@@ -305,7 +355,7 @@ uv run tangle sdk published-components deprecate sha256:old --superseded-by sha2
|
|
|
305
355
|
|
|
306
356
|
`publish` accepts `--image`, `--name`, `--description`, `--annotations` (JSON), `--dry-run`, `--published-by`, generic git metadata fields, generic API auth fields, `--log-type`, and `--config`. By default it scopes version checks and automatic old-version deprecation to the current authenticated user via `users_me()`; use `--published-by` to supply an explicit owner/publisher filter. Publishing fails closed if no owner can be determined.
|
|
307
357
|
|
|
308
|
-
There is no separate OSS `publish-all` command. To publish multiple components, pass a YAML/JSON config list, or `_defaults` + `configs`, to the same `published-components publish` command; the command aggregates results and exits nonzero if any component errors.
|
|
358
|
+
There is no separate OSS `publish-all` command. To publish multiple components, pass a YAML/JSON config list, or `_defaults` + `configs`, to the same `published-components publish` command; the command aggregates results and exits nonzero if any component errors. A top-level `_select` node can choose between such documents per environment (see [Environment-selected configs](#environment-selected-configs-_select)).
|
|
309
359
|
|
|
310
360
|
```yaml
|
|
311
361
|
_defaults:
|
|
@@ -336,6 +386,7 @@ Pipeline run API/submit commands live under `sdk pipeline-runs`:
|
|
|
336
386
|
```bash
|
|
337
387
|
uv run tangle sdk pipeline-runs submit pipeline.yaml --dry-run
|
|
338
388
|
uv run tangle sdk pipeline-runs submit pipeline.yaml --arg key=value --annotation owner=team
|
|
389
|
+
uv run tangle sdk pipeline-runs submit-from-python pipeline.py --arg key=value
|
|
339
390
|
uv run tangle sdk pipeline-runs wait RUN_ID --max-wait 600 --poll-interval 10
|
|
340
391
|
uv run tangle sdk pipeline-runs logs EXECUTION_ID
|
|
341
392
|
uv run tangle sdk pipeline-runs annotations set RUN_ID key value
|
|
@@ -351,6 +402,59 @@ uv run tangle sdk pipelines compile pipeline.py -o pipeline.yaml
|
|
|
351
402
|
uv run tangle sdk pipelines compile pipeline.py -o pipeline.yaml --pipeline pipeline_fn_name
|
|
352
403
|
```
|
|
353
404
|
|
|
405
|
+
To compile and submit in one step, without keeping the compiled YAML around, use
|
|
406
|
+
`pipeline-runs submit-from-python`:
|
|
407
|
+
|
|
408
|
+
```bash
|
|
409
|
+
uv run tangle sdk pipeline-runs submit-from-python pipeline.py \
|
|
410
|
+
--override batch_size=100 \
|
|
411
|
+
--image eval-slim=registry.example/eval-slim@sha256:... \
|
|
412
|
+
--arg shop=acme --annotation owner=team
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
It compiles the script, hydrates the bundle, submits the run, and removes the
|
|
416
|
+
compiled artifacts again — including on dry runs and failures. Its run-tier
|
|
417
|
+
flags are the same as `pipeline-runs submit`; the extra compile-tier flags are
|
|
418
|
+
`--pipeline`, repeatable `--override KEY=VALUE`, and repeatable `--image ID=REF`.
|
|
419
|
+
Use `pipelines compile` instead when the compiled YAML itself is what you want.
|
|
420
|
+
|
|
421
|
+
The two value tiers are distinct and easy to confuse:
|
|
422
|
+
|
|
423
|
+
| Flag | Tier | Meaning |
|
|
424
|
+
| --- | --- | --- |
|
|
425
|
+
| `--override KEY=VALUE` | compile | `cfg` value used while the graph is built |
|
|
426
|
+
| `--image ID=REF` | compile | resolves `@task(image_id=ID)` to a registry ref |
|
|
427
|
+
| `--arg` / `--args-json` / `--arg-secret` | run | pipeline arguments for the created run |
|
|
428
|
+
|
|
429
|
+
Notes:
|
|
430
|
+
|
|
431
|
+
- Hydration is always on: the compiled bundle references local sidecars
|
|
432
|
+
(`resolve://./<stem>.components.yaml#…`, `file://<stem>.subgraphs/…`) that the
|
|
433
|
+
server cannot read. There is no `--no-hydrate` here.
|
|
434
|
+
- The bundle is compiled next to the script (never in `/tmp`) under a unique
|
|
435
|
+
hidden `.tangle-submit-*.yaml` name, because relative refs such as
|
|
436
|
+
`ref(url="file://./component.yaml")` resolve against the *output* directory.
|
|
437
|
+
The name is allocated with an exclusive create, so concurrent compiles of the
|
|
438
|
+
same script never collide or overwrite a sibling YAML. A symlinked script
|
|
439
|
+
compiles next to its resolved target, where its `config.yaml` and relative
|
|
440
|
+
refs actually live.
|
|
441
|
+
- The bundle stays readable until every run has been submitted, so
|
|
442
|
+
run-lifecycle hooks still see an existing `pipeline_path`; cleanup then
|
|
443
|
+
removes exactly that stem's files (`.yaml`, `.components.yaml`,
|
|
444
|
+
`.subgraphs/`) and nothing else.
|
|
445
|
+
- Submission never waits; use `pipeline-runs wait RUN_ID`.
|
|
446
|
+
- With a multi-entry `--config` file, entries may carry different `--override` /
|
|
447
|
+
`--image` values, and **every entry is fully prepared before any run is
|
|
448
|
+
created**: each is compiled exactly once, hydrated, merged with its run
|
|
449
|
+
arguments and secrets, validated, and frozen into a submit body; only then are
|
|
450
|
+
the frozen bodies submitted in order (no recompilation). An unsupported config
|
|
451
|
+
key (`hydrate:`, `pipeline_path:`), a malformed `override` / `image` /
|
|
452
|
+
`arg-secret` value, an input given as both `--arg` and `--arg-secret`, a
|
|
453
|
+
missing script, or a compile/hydrate error in *any* entry therefore creates no
|
|
454
|
+
runs and leaves no artifacts behind. A runtime failure while submitting entry
|
|
455
|
+
N can still follow the successful submits of entries 1..N-1 — that is inherent
|
|
456
|
+
to creating N runs.
|
|
457
|
+
|
|
354
458
|
A minimal graph uses `@pipeline` for the graph and `@task` for local Python components. `@task` functions are not executed at compile time; the compiler records call sites, emits a sibling `<output>.components.yaml` with `local_from_python` entries, and rewrites task component refs to that sidecar. Hydrate later regenerates the same component YAML from the Python source.
|
|
355
459
|
|
|
356
460
|
```python
|
|
@@ -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.
|
|
17
|
+
__version__ = "0.1.12"
|
|
18
18
|
|
|
19
19
|
__all__ = ["TangleDynamicDiscoveryClient", "__version__"]
|