orchestra-cli 0.2.0__tar.gz → 0.3.0__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.
- {orchestra_cli-0.2.0 → orchestra_cli-0.3.0}/PKG-INFO +45 -2
- {orchestra_cli-0.2.0 → orchestra_cli-0.3.0}/README.md +44 -1
- {orchestra_cli-0.2.0 → orchestra_cli-0.3.0}/orchestra_cli/src/cli.py +4 -0
- orchestra_cli-0.3.0/orchestra_cli/src/delete_pipeline.py +39 -0
- orchestra_cli-0.3.0/orchestra_cli/src/fetch_pipelines.py +45 -0
- {orchestra_cli-0.2.0 → orchestra_cli-0.3.0}/orchestra_cli/tests/test_cli.py +2 -0
- orchestra_cli-0.3.0/orchestra_cli/tests/test_delete_pipeline.py +82 -0
- orchestra_cli-0.3.0/orchestra_cli/tests/test_fetch_pipelines.py +78 -0
- {orchestra_cli-0.2.0 → orchestra_cli-0.3.0}/orchestra_cli/utils/constants.py +4 -0
- {orchestra_cli-0.2.0 → orchestra_cli-0.3.0}/orchestra_cli.egg-info/PKG-INFO +45 -2
- {orchestra_cli-0.2.0 → orchestra_cli-0.3.0}/orchestra_cli.egg-info/SOURCES.txt +4 -0
- {orchestra_cli-0.2.0 → orchestra_cli-0.3.0}/pyproject.toml +1 -1
- {orchestra_cli-0.2.0 → orchestra_cli-0.3.0}/orchestra_cli/src/__init__.py +0 -0
- {orchestra_cli-0.2.0 → orchestra_cli-0.3.0}/orchestra_cli/src/create_pipeline.py +0 -0
- {orchestra_cli-0.2.0 → orchestra_cli-0.3.0}/orchestra_cli/src/import_pipeline.py +0 -0
- {orchestra_cli-0.2.0 → orchestra_cli-0.3.0}/orchestra_cli/src/pipeline_upsert.py +0 -0
- {orchestra_cli-0.2.0 → orchestra_cli-0.3.0}/orchestra_cli/src/run_pipeline.py +0 -0
- {orchestra_cli-0.2.0 → orchestra_cli-0.3.0}/orchestra_cli/src/update_pipeline.py +0 -0
- {orchestra_cli-0.2.0 → orchestra_cli-0.3.0}/orchestra_cli/src/validate_pipeline.py +0 -0
- {orchestra_cli-0.2.0 → orchestra_cli-0.3.0}/orchestra_cli/tests/__init__.py +0 -0
- {orchestra_cli-0.2.0 → orchestra_cli-0.3.0}/orchestra_cli/tests/conftest.py +0 -0
- {orchestra_cli-0.2.0 → orchestra_cli-0.3.0}/orchestra_cli/tests/test_create_pipeline.py +0 -0
- {orchestra_cli-0.2.0 → orchestra_cli-0.3.0}/orchestra_cli/tests/test_import_pipeline.py +0 -0
- {orchestra_cli-0.2.0 → orchestra_cli-0.3.0}/orchestra_cli/tests/test_run_pipeline.py +0 -0
- {orchestra_cli-0.2.0 → orchestra_cli-0.3.0}/orchestra_cli/tests/test_update_pipeline.py +0 -0
- {orchestra_cli-0.2.0 → orchestra_cli-0.3.0}/orchestra_cli/tests/test_validate_pipeline.py +0 -0
- {orchestra_cli-0.2.0 → orchestra_cli-0.3.0}/orchestra_cli/utils/git.py +0 -0
- {orchestra_cli-0.2.0 → orchestra_cli-0.3.0}/orchestra_cli/utils/styling.py +0 -0
- {orchestra_cli-0.2.0 → orchestra_cli-0.3.0}/orchestra_cli.egg-info/dependency_links.txt +0 -0
- {orchestra_cli-0.2.0 → orchestra_cli-0.3.0}/orchestra_cli.egg-info/entry_points.txt +0 -0
- {orchestra_cli-0.2.0 → orchestra_cli-0.3.0}/orchestra_cli.egg-info/requires.txt +0 -0
- {orchestra_cli-0.2.0 → orchestra_cli-0.3.0}/orchestra_cli.egg-info/top_level.txt +0 -0
- {orchestra_cli-0.2.0 → orchestra_cli-0.3.0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: orchestra-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: Orchestra CLI. Perform operations with Orchestra locally.
|
|
5
5
|
Author-email: Orchestra Technologies <support@getorchestra.io>
|
|
6
6
|
Requires-Python: >=3.10
|
|
@@ -31,15 +31,17 @@ pipx install orchestra-cli
|
|
|
31
31
|
|
|
32
32
|
## Environment variables
|
|
33
33
|
|
|
34
|
-
- `ORCHESTRA_API_KEY`: Required for actions that call the API (`import`, `run`).
|
|
34
|
+
- `ORCHESTRA_API_KEY`: Required for actions that call the API (`import`, `create-pipeline`, `update-pipeline`, `delete-pipeline`, `run`).
|
|
35
35
|
- `BASE_URL`: Optional. Override the default Orchestra host (`https://app.getorchestra.io`) for non‑production/testing.
|
|
36
36
|
|
|
37
37
|
## Commands overview
|
|
38
38
|
|
|
39
39
|
- `validate`: Validate a pipeline YAML locally against the Orchestra API schema.
|
|
40
40
|
- `import`: Register a pipeline YAML (from a git repo) with Orchestra under an alias.
|
|
41
|
+
- `fetch-pipelines`: Fetch the pipelines visible to the current API key as JSON.
|
|
41
42
|
- `create-pipeline`: Create an Orchestra-backed pipeline from a local YAML file.
|
|
42
43
|
- `update-pipeline`: Update an existing Orchestra-backed pipeline from a local YAML file.
|
|
44
|
+
- `delete-pipeline`: Delete an existing pipeline by alias.
|
|
43
45
|
- `run`: Start a pipeline run by alias, optionally pinning branch/commit and waiting for completion.
|
|
44
46
|
|
|
45
47
|
Use `orchestra --help` or `orchestra <command> --help` for built-in help.
|
|
@@ -149,6 +151,24 @@ Behavior
|
|
|
149
151
|
|
|
150
152
|
---
|
|
151
153
|
|
|
154
|
+
## fetch-pipelines
|
|
155
|
+
|
|
156
|
+
Fetch the pipelines available to the current Orchestra API key.
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
export ORCHESTRA_API_KEY=...
|
|
160
|
+
|
|
161
|
+
orchestra fetch-pipelines
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
Behavior
|
|
165
|
+
|
|
166
|
+
- Sends `GET /api/engine/public/pipelines`. Responses always include each pipeline's latest run metadata.
|
|
167
|
+
- Prints the response payload as pretty JSON for scripting and inspection.
|
|
168
|
+
- Exit codes: `0` on success, `1` on failure.
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
152
172
|
## update-pipeline
|
|
153
173
|
|
|
154
174
|
Update an existing Orchestra-backed pipeline from a local YAML file.
|
|
@@ -178,6 +198,29 @@ Behavior
|
|
|
178
198
|
|
|
179
199
|
---
|
|
180
200
|
|
|
201
|
+
## delete-pipeline
|
|
202
|
+
|
|
203
|
+
Delete a pipeline by alias.
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
export ORCHESTRA_API_KEY=...
|
|
207
|
+
|
|
208
|
+
orchestra delete-pipeline --alias my-pipeline
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
Options
|
|
212
|
+
|
|
213
|
+
- `-a, --alias` (required): Pipeline alias to delete.
|
|
214
|
+
|
|
215
|
+
Behavior
|
|
216
|
+
|
|
217
|
+
- Sends `DELETE /pipelines/{alias}` with API key authentication.
|
|
218
|
+
- Deletes the pipeline resolved by alias within the authenticated account.
|
|
219
|
+
- On success, exits with code `0` after printing a confirmation message.
|
|
220
|
+
- Exit codes: `0` on success, `1` on failure.
|
|
221
|
+
|
|
222
|
+
---
|
|
223
|
+
|
|
181
224
|
## run
|
|
182
225
|
|
|
183
226
|
Start a pipeline run by alias. Optionally specify a branch and/or commit. By default, the command waits and polls the run status until completion.
|
|
@@ -20,15 +20,17 @@ pipx install orchestra-cli
|
|
|
20
20
|
|
|
21
21
|
## Environment variables
|
|
22
22
|
|
|
23
|
-
- `ORCHESTRA_API_KEY`: Required for actions that call the API (`import`, `run`).
|
|
23
|
+
- `ORCHESTRA_API_KEY`: Required for actions that call the API (`import`, `create-pipeline`, `update-pipeline`, `delete-pipeline`, `run`).
|
|
24
24
|
- `BASE_URL`: Optional. Override the default Orchestra host (`https://app.getorchestra.io`) for non‑production/testing.
|
|
25
25
|
|
|
26
26
|
## Commands overview
|
|
27
27
|
|
|
28
28
|
- `validate`: Validate a pipeline YAML locally against the Orchestra API schema.
|
|
29
29
|
- `import`: Register a pipeline YAML (from a git repo) with Orchestra under an alias.
|
|
30
|
+
- `fetch-pipelines`: Fetch the pipelines visible to the current API key as JSON.
|
|
30
31
|
- `create-pipeline`: Create an Orchestra-backed pipeline from a local YAML file.
|
|
31
32
|
- `update-pipeline`: Update an existing Orchestra-backed pipeline from a local YAML file.
|
|
33
|
+
- `delete-pipeline`: Delete an existing pipeline by alias.
|
|
32
34
|
- `run`: Start a pipeline run by alias, optionally pinning branch/commit and waiting for completion.
|
|
33
35
|
|
|
34
36
|
Use `orchestra --help` or `orchestra <command> --help` for built-in help.
|
|
@@ -138,6 +140,24 @@ Behavior
|
|
|
138
140
|
|
|
139
141
|
---
|
|
140
142
|
|
|
143
|
+
## fetch-pipelines
|
|
144
|
+
|
|
145
|
+
Fetch the pipelines available to the current Orchestra API key.
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
export ORCHESTRA_API_KEY=...
|
|
149
|
+
|
|
150
|
+
orchestra fetch-pipelines
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
Behavior
|
|
154
|
+
|
|
155
|
+
- Sends `GET /api/engine/public/pipelines`. Responses always include each pipeline's latest run metadata.
|
|
156
|
+
- Prints the response payload as pretty JSON for scripting and inspection.
|
|
157
|
+
- Exit codes: `0` on success, `1` on failure.
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
141
161
|
## update-pipeline
|
|
142
162
|
|
|
143
163
|
Update an existing Orchestra-backed pipeline from a local YAML file.
|
|
@@ -167,6 +187,29 @@ Behavior
|
|
|
167
187
|
|
|
168
188
|
---
|
|
169
189
|
|
|
190
|
+
## delete-pipeline
|
|
191
|
+
|
|
192
|
+
Delete a pipeline by alias.
|
|
193
|
+
|
|
194
|
+
```bash
|
|
195
|
+
export ORCHESTRA_API_KEY=...
|
|
196
|
+
|
|
197
|
+
orchestra delete-pipeline --alias my-pipeline
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
Options
|
|
201
|
+
|
|
202
|
+
- `-a, --alias` (required): Pipeline alias to delete.
|
|
203
|
+
|
|
204
|
+
Behavior
|
|
205
|
+
|
|
206
|
+
- Sends `DELETE /pipelines/{alias}` with API key authentication.
|
|
207
|
+
- Deletes the pipeline resolved by alias within the authenticated account.
|
|
208
|
+
- On success, exits with code `0` after printing a confirmation message.
|
|
209
|
+
- Exit codes: `0` on success, `1` on failure.
|
|
210
|
+
|
|
211
|
+
---
|
|
212
|
+
|
|
170
213
|
## run
|
|
171
214
|
|
|
172
215
|
Start a pipeline run by alias. Optionally specify a branch and/or commit. By default, the command waits and polls the run status until completion.
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import typer
|
|
2
2
|
|
|
3
3
|
from .create_pipeline import create_pipeline
|
|
4
|
+
from .delete_pipeline import delete_pipeline
|
|
5
|
+
from .fetch_pipelines import fetch_pipelines
|
|
4
6
|
from .import_pipeline import import_pipeline
|
|
5
7
|
from .run_pipeline import run_pipeline
|
|
6
8
|
from .update_pipeline import update_pipeline
|
|
@@ -12,5 +14,7 @@ app = typer.Typer(help="Orchestra CLI – perform operations with Orchestra loca
|
|
|
12
14
|
app.command(name="validate")(validate)
|
|
13
15
|
app.command(name="import")(import_pipeline)
|
|
14
16
|
app.command(name="run")(run_pipeline)
|
|
17
|
+
app.command(name="fetch-pipelines")(fetch_pipelines)
|
|
15
18
|
app.command(name="create-pipeline")(create_pipeline)
|
|
16
19
|
app.command(name="update-pipeline")(update_pipeline)
|
|
20
|
+
app.command(name="delete-pipeline")(delete_pipeline)
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import json
|
|
2
|
+
|
|
3
|
+
import httpx
|
|
4
|
+
import typer
|
|
5
|
+
|
|
6
|
+
from ..utils.constants import get_delete_pipeline_url
|
|
7
|
+
from ..utils.styling import green, indent_message, red, yellow
|
|
8
|
+
from .pipeline_upsert import require_api_key
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def delete_pipeline(
|
|
12
|
+
alias: str = typer.Option(..., "--alias", "-a", help="Pipeline alias"),
|
|
13
|
+
):
|
|
14
|
+
"""
|
|
15
|
+
Delete a pipeline by alias.
|
|
16
|
+
"""
|
|
17
|
+
api_key = require_api_key()
|
|
18
|
+
|
|
19
|
+
try:
|
|
20
|
+
response = httpx.delete(
|
|
21
|
+
get_delete_pipeline_url(alias),
|
|
22
|
+
timeout=30,
|
|
23
|
+
headers={"Authorization": f"Bearer {api_key}"},
|
|
24
|
+
)
|
|
25
|
+
except Exception as e:
|
|
26
|
+
typer.echo(red(f"HTTP request failed: {e}"))
|
|
27
|
+
raise typer.Exit(code=1)
|
|
28
|
+
|
|
29
|
+
if response.status_code == 204:
|
|
30
|
+
typer.echo(green(f"✅ Pipeline '{alias}' deleted successfully"))
|
|
31
|
+
raise typer.Exit(code=0)
|
|
32
|
+
|
|
33
|
+
typer.echo(red(f"❌ Delete failed with status {response.status_code}"))
|
|
34
|
+
try:
|
|
35
|
+
typer.echo(yellow(indent_message(json.dumps(response.json(), indent=2))))
|
|
36
|
+
except Exception:
|
|
37
|
+
if response.text:
|
|
38
|
+
typer.echo(yellow(indent_message(response.text)))
|
|
39
|
+
raise typer.Exit(code=1)
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import json
|
|
2
|
+
|
|
3
|
+
import httpx
|
|
4
|
+
import typer
|
|
5
|
+
|
|
6
|
+
from ..utils.constants import get_api_url
|
|
7
|
+
from ..utils.styling import indent_message, red, yellow
|
|
8
|
+
from .pipeline_upsert import require_api_key
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def fetch_pipelines():
|
|
12
|
+
"""
|
|
13
|
+
Fetch pipelines available to the current Orchestra API key.
|
|
14
|
+
|
|
15
|
+
The API always includes each pipeline's latest run metadata.
|
|
16
|
+
"""
|
|
17
|
+
api_key = require_api_key()
|
|
18
|
+
|
|
19
|
+
try:
|
|
20
|
+
response = httpx.get(
|
|
21
|
+
get_api_url(""),
|
|
22
|
+
timeout=30,
|
|
23
|
+
headers={"Authorization": f"Bearer {api_key}"},
|
|
24
|
+
)
|
|
25
|
+
except Exception as e:
|
|
26
|
+
typer.echo(red(f"HTTP request failed: {e}"))
|
|
27
|
+
raise typer.Exit(code=1)
|
|
28
|
+
|
|
29
|
+
if response.status_code == 200:
|
|
30
|
+
try:
|
|
31
|
+
pipelines = response.json()
|
|
32
|
+
except Exception:
|
|
33
|
+
typer.echo(red("❌ Fetch pipelines failed: success response was not valid JSON"))
|
|
34
|
+
typer.echo(yellow(indent_message(response.text)))
|
|
35
|
+
raise typer.Exit(code=1)
|
|
36
|
+
|
|
37
|
+
typer.echo(json.dumps(pipelines, indent=2))
|
|
38
|
+
raise typer.Exit(code=0)
|
|
39
|
+
|
|
40
|
+
typer.echo(red(f"❌ Fetch pipelines failed with status {response.status_code}"))
|
|
41
|
+
try:
|
|
42
|
+
typer.echo(yellow(indent_message(json.dumps(response.json(), indent=2))))
|
|
43
|
+
except Exception:
|
|
44
|
+
typer.echo(yellow(indent_message(response.text)))
|
|
45
|
+
raise typer.Exit(code=1)
|
|
@@ -10,5 +10,7 @@ def test_help():
|
|
|
10
10
|
assert result.exit_code == 0
|
|
11
11
|
assert "Orchestra CLI" in result.output
|
|
12
12
|
assert "validate" in result.output
|
|
13
|
+
assert "fetch-pipelines" in result.output
|
|
13
14
|
assert "create-pipeline" in result.output
|
|
15
|
+
assert "delete-pipeline" in result.output
|
|
14
16
|
assert "update-pipeline" in result.output
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import httpx
|
|
2
|
+
import pytest
|
|
3
|
+
from pytest_httpx import HTTPXMock
|
|
4
|
+
from typer.testing import CliRunner
|
|
5
|
+
|
|
6
|
+
from orchestra_cli.src.cli import app
|
|
7
|
+
|
|
8
|
+
runner = CliRunner()
|
|
9
|
+
mock_api_key = "fake-key"
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@pytest.fixture(autouse=True)
|
|
13
|
+
def mock_env(monkeypatch):
|
|
14
|
+
monkeypatch.setenv("ORCHESTRA_API_KEY", mock_api_key)
|
|
15
|
+
monkeypatch.setenv("BASE_URL", "")
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def test_delete_success(httpx_mock: HTTPXMock):
|
|
19
|
+
alias = "demo"
|
|
20
|
+
httpx_mock.add_response(
|
|
21
|
+
method="DELETE",
|
|
22
|
+
url="https://app.getorchestra.io/api/engine/public/pipelines/demo",
|
|
23
|
+
match_headers={"Authorization": f"Bearer {mock_api_key}"},
|
|
24
|
+
status_code=204,
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
result = runner.invoke(app, ["delete-pipeline", "--alias", alias])
|
|
28
|
+
|
|
29
|
+
assert result.exit_code == 0
|
|
30
|
+
assert "deleted successfully" in result.output
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def test_delete_uuid_like_alias_uses_alias_path(httpx_mock: HTTPXMock):
|
|
34
|
+
alias = "798d7121-6809-4148-aecb-26740cfabdf1"
|
|
35
|
+
httpx_mock.add_response(
|
|
36
|
+
method="DELETE",
|
|
37
|
+
url=f"https://app.getorchestra.io/api/engine/public/pipelines/{alias}",
|
|
38
|
+
match_headers={"Authorization": f"Bearer {mock_api_key}"},
|
|
39
|
+
status_code=204,
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
result = runner.invoke(app, ["delete-pipeline", "--alias", alias])
|
|
43
|
+
|
|
44
|
+
assert result.exit_code == 0
|
|
45
|
+
assert "deleted successfully" in result.output
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def test_delete_missing_api_key(monkeypatch):
|
|
49
|
+
monkeypatch.delenv("ORCHESTRA_API_KEY", raising=False)
|
|
50
|
+
|
|
51
|
+
result = runner.invoke(app, ["delete-pipeline", "--alias", "demo"])
|
|
52
|
+
|
|
53
|
+
assert result.exit_code == 1
|
|
54
|
+
assert "ORCHESTRA_API_KEY is not set" in result.output
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def test_delete_http_request_failure(monkeypatch):
|
|
58
|
+
def raise_timeout(*args, **kwargs): # noqa: ARG001
|
|
59
|
+
raise httpx.TimeoutException("timed out")
|
|
60
|
+
|
|
61
|
+
monkeypatch.setattr(httpx, "delete", raise_timeout)
|
|
62
|
+
|
|
63
|
+
result = runner.invoke(app, ["delete-pipeline", "--alias", "demo"])
|
|
64
|
+
|
|
65
|
+
assert result.exit_code == 1
|
|
66
|
+
assert "HTTP request failed" in result.output
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def test_delete_api_error(httpx_mock: HTTPXMock):
|
|
70
|
+
httpx_mock.add_response(
|
|
71
|
+
method="DELETE",
|
|
72
|
+
url="https://app.getorchestra.io/api/engine/public/pipelines/demo",
|
|
73
|
+
match_headers={"Authorization": f"Bearer {mock_api_key}"},
|
|
74
|
+
json={"detail": "Pipeline not found"},
|
|
75
|
+
status_code=404,
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
result = runner.invoke(app, ["delete-pipeline", "--alias", "demo"])
|
|
79
|
+
|
|
80
|
+
assert result.exit_code == 1
|
|
81
|
+
assert "Delete failed with status 404" in result.output
|
|
82
|
+
assert "Pipeline not found" in result.output
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import json
|
|
2
|
+
|
|
3
|
+
import pytest
|
|
4
|
+
from pytest_httpx import HTTPXMock
|
|
5
|
+
from typer.testing import CliRunner
|
|
6
|
+
|
|
7
|
+
from orchestra_cli.src.cli import app
|
|
8
|
+
|
|
9
|
+
runner = CliRunner()
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@pytest.fixture(autouse=True)
|
|
13
|
+
def mock_env(monkeypatch):
|
|
14
|
+
monkeypatch.setenv("ORCHESTRA_API_KEY", "fake-key")
|
|
15
|
+
monkeypatch.setenv("BASE_URL", "")
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def test_fetch_pipelines_success(httpx_mock: HTTPXMock):
|
|
19
|
+
pipelines = [
|
|
20
|
+
{
|
|
21
|
+
"id": "pipe-1",
|
|
22
|
+
"alias": "demo",
|
|
23
|
+
"name": "Demo pipeline",
|
|
24
|
+
"latestRunStatus": "SUCCEEDED",
|
|
25
|
+
},
|
|
26
|
+
]
|
|
27
|
+
httpx_mock.add_response(
|
|
28
|
+
method="GET",
|
|
29
|
+
url="https://app.getorchestra.io/api/engine/public/pipelines",
|
|
30
|
+
json=pipelines,
|
|
31
|
+
status_code=200,
|
|
32
|
+
match_headers={"Authorization": "Bearer fake-key"},
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
result = runner.invoke(app, ["fetch-pipelines"])
|
|
36
|
+
|
|
37
|
+
assert result.exit_code == 0
|
|
38
|
+
assert result.output == f"{json.dumps(pipelines, indent=2)}\n"
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def test_fetch_pipelines_missing_api_key(monkeypatch):
|
|
42
|
+
monkeypatch.delenv("ORCHESTRA_API_KEY", raising=False)
|
|
43
|
+
|
|
44
|
+
result = runner.invoke(app, ["fetch-pipelines"])
|
|
45
|
+
|
|
46
|
+
assert result.exit_code == 1
|
|
47
|
+
assert "ORCHESTRA_API_KEY is not set" in result.output
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def test_fetch_pipelines_api_error(httpx_mock: HTTPXMock):
|
|
51
|
+
httpx_mock.add_response(
|
|
52
|
+
method="GET",
|
|
53
|
+
url="https://app.getorchestra.io/api/engine/public/pipelines",
|
|
54
|
+
json={"detail": "Forbidden"},
|
|
55
|
+
status_code=403,
|
|
56
|
+
match_headers={"Authorization": "Bearer fake-key"},
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
result = runner.invoke(app, ["fetch-pipelines"])
|
|
60
|
+
|
|
61
|
+
assert result.exit_code == 1
|
|
62
|
+
assert "Fetch pipelines failed with status 403" in result.output
|
|
63
|
+
assert "Forbidden" in result.output
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def test_fetch_pipelines_invalid_success_json(httpx_mock: HTTPXMock):
|
|
67
|
+
httpx_mock.add_response(
|
|
68
|
+
method="GET",
|
|
69
|
+
url="https://app.getorchestra.io/api/engine/public/pipelines",
|
|
70
|
+
text="ok",
|
|
71
|
+
status_code=200,
|
|
72
|
+
match_headers={"Authorization": "Bearer fake-key"},
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
result = runner.invoke(app, ["fetch-pipelines"])
|
|
76
|
+
|
|
77
|
+
assert result.exit_code == 1
|
|
78
|
+
assert "success response was not valid JSON" in result.output
|
|
@@ -24,5 +24,9 @@ def get_update_pipeline_url(alias: str) -> str:
|
|
|
24
24
|
return get_api_url(alias)
|
|
25
25
|
|
|
26
26
|
|
|
27
|
+
def get_delete_pipeline_url(alias: str) -> str:
|
|
28
|
+
return get_api_url(alias)
|
|
29
|
+
|
|
30
|
+
|
|
27
31
|
def get_pipeline_edit_url(pipeline_id: str) -> str:
|
|
28
32
|
return f"{get_base_url()}/pipelines/{pipeline_id}/edit"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: orchestra-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: Orchestra CLI. Perform operations with Orchestra locally.
|
|
5
5
|
Author-email: Orchestra Technologies <support@getorchestra.io>
|
|
6
6
|
Requires-Python: >=3.10
|
|
@@ -31,15 +31,17 @@ pipx install orchestra-cli
|
|
|
31
31
|
|
|
32
32
|
## Environment variables
|
|
33
33
|
|
|
34
|
-
- `ORCHESTRA_API_KEY`: Required for actions that call the API (`import`, `run`).
|
|
34
|
+
- `ORCHESTRA_API_KEY`: Required for actions that call the API (`import`, `create-pipeline`, `update-pipeline`, `delete-pipeline`, `run`).
|
|
35
35
|
- `BASE_URL`: Optional. Override the default Orchestra host (`https://app.getorchestra.io`) for non‑production/testing.
|
|
36
36
|
|
|
37
37
|
## Commands overview
|
|
38
38
|
|
|
39
39
|
- `validate`: Validate a pipeline YAML locally against the Orchestra API schema.
|
|
40
40
|
- `import`: Register a pipeline YAML (from a git repo) with Orchestra under an alias.
|
|
41
|
+
- `fetch-pipelines`: Fetch the pipelines visible to the current API key as JSON.
|
|
41
42
|
- `create-pipeline`: Create an Orchestra-backed pipeline from a local YAML file.
|
|
42
43
|
- `update-pipeline`: Update an existing Orchestra-backed pipeline from a local YAML file.
|
|
44
|
+
- `delete-pipeline`: Delete an existing pipeline by alias.
|
|
43
45
|
- `run`: Start a pipeline run by alias, optionally pinning branch/commit and waiting for completion.
|
|
44
46
|
|
|
45
47
|
Use `orchestra --help` or `orchestra <command> --help` for built-in help.
|
|
@@ -149,6 +151,24 @@ Behavior
|
|
|
149
151
|
|
|
150
152
|
---
|
|
151
153
|
|
|
154
|
+
## fetch-pipelines
|
|
155
|
+
|
|
156
|
+
Fetch the pipelines available to the current Orchestra API key.
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
export ORCHESTRA_API_KEY=...
|
|
160
|
+
|
|
161
|
+
orchestra fetch-pipelines
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
Behavior
|
|
165
|
+
|
|
166
|
+
- Sends `GET /api/engine/public/pipelines`. Responses always include each pipeline's latest run metadata.
|
|
167
|
+
- Prints the response payload as pretty JSON for scripting and inspection.
|
|
168
|
+
- Exit codes: `0` on success, `1` on failure.
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
152
172
|
## update-pipeline
|
|
153
173
|
|
|
154
174
|
Update an existing Orchestra-backed pipeline from a local YAML file.
|
|
@@ -178,6 +198,29 @@ Behavior
|
|
|
178
198
|
|
|
179
199
|
---
|
|
180
200
|
|
|
201
|
+
## delete-pipeline
|
|
202
|
+
|
|
203
|
+
Delete a pipeline by alias.
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
export ORCHESTRA_API_KEY=...
|
|
207
|
+
|
|
208
|
+
orchestra delete-pipeline --alias my-pipeline
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
Options
|
|
212
|
+
|
|
213
|
+
- `-a, --alias` (required): Pipeline alias to delete.
|
|
214
|
+
|
|
215
|
+
Behavior
|
|
216
|
+
|
|
217
|
+
- Sends `DELETE /pipelines/{alias}` with API key authentication.
|
|
218
|
+
- Deletes the pipeline resolved by alias within the authenticated account.
|
|
219
|
+
- On success, exits with code `0` after printing a confirmation message.
|
|
220
|
+
- Exit codes: `0` on success, `1` on failure.
|
|
221
|
+
|
|
222
|
+
---
|
|
223
|
+
|
|
181
224
|
## run
|
|
182
225
|
|
|
183
226
|
Start a pipeline run by alias. Optionally specify a branch and/or commit. By default, the command waits and polls the run status until completion.
|
|
@@ -9,6 +9,8 @@ orchestra_cli.egg-info/top_level.txt
|
|
|
9
9
|
orchestra_cli/src/__init__.py
|
|
10
10
|
orchestra_cli/src/cli.py
|
|
11
11
|
orchestra_cli/src/create_pipeline.py
|
|
12
|
+
orchestra_cli/src/delete_pipeline.py
|
|
13
|
+
orchestra_cli/src/fetch_pipelines.py
|
|
12
14
|
orchestra_cli/src/import_pipeline.py
|
|
13
15
|
orchestra_cli/src/pipeline_upsert.py
|
|
14
16
|
orchestra_cli/src/run_pipeline.py
|
|
@@ -18,6 +20,8 @@ orchestra_cli/tests/__init__.py
|
|
|
18
20
|
orchestra_cli/tests/conftest.py
|
|
19
21
|
orchestra_cli/tests/test_cli.py
|
|
20
22
|
orchestra_cli/tests/test_create_pipeline.py
|
|
23
|
+
orchestra_cli/tests/test_delete_pipeline.py
|
|
24
|
+
orchestra_cli/tests/test_fetch_pipelines.py
|
|
21
25
|
orchestra_cli/tests/test_import_pipeline.py
|
|
22
26
|
orchestra_cli/tests/test_run_pipeline.py
|
|
23
27
|
orchestra_cli/tests/test_update_pipeline.py
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|