ellf-cli 3.1.3__tar.gz → 4.0.3__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.
- {ellf_cli-3.1.3/ellf_cli.egg-info → ellf_cli-4.0.3}/PKG-INFO +3 -3
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/README.md +8 -7
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli/about.json +3 -2
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli/auth.py +21 -21
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli/cli.py +5 -5
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli/cloud/gcp.py +4 -4
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli/commands/_recipe_file.py +1 -1
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli/commands/_recipe_subcommand.py +17 -17
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli/commands/actions.py +3 -3
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli/commands/agents.py +3 -3
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli/commands/assets.py +5 -5
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli/commands/clusters.py +14 -14
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli/commands/datasets.py +7 -7
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli/commands/files/cp.py +2 -2
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli/commands/files/ls.py +1 -1
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli/commands/files/rm.py +2 -2
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli/commands/files/rsync.py +2 -2
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli/commands/files/stats.py +1 -1
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli/commands/general.py +79 -20
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli/commands/import_export.py +3 -3
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli/commands/infra/_helpers.py +8 -10
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli/commands/infra/deploy.py +12 -14
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli/commands/infra/init_values.py +4 -4
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli/commands/infra/register.py +2 -2
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli/commands/infra/start.py +1 -1
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli/commands/jobs.py +1 -1
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli/commands/packages.py +8 -8
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli/commands/paths.py +7 -7
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli/commands/projects.py +7 -7
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli/commands/publish_code.py +6 -6
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli/commands/publish_data.py +1 -1
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli/commands/recipes.py +3 -3
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli/commands/secrets.py +10 -10
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli/commands/support.py +119 -38
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli/commands/tasks.py +3 -3
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli/commands/todos.py +2 -2
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli/ellf.json +27 -14
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli/errors.py +11 -11
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli/helm.py +8 -8
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli/messages.py +3 -3
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli/query.py +24 -24
- ellf_cli-4.0.3/ellf_cli/recipes_cookiecutter/{{cookiecutter.package_dir}}/requirements.in +1 -0
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli/recipes_cookiecutter/{{cookiecutter.package_dir}}/{{cookiecutter.package_name}}/recipes/example_task.py +1 -1
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli/ui.py +9 -5
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli/util.py +3 -3
- {ellf_cli-3.1.3 → ellf_cli-4.0.3/ellf_cli.egg-info}/PKG-INFO +3 -3
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli.egg-info/SOURCES.txt +0 -1
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli.egg-info/requires.txt +2 -2
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/pyproject.toml +3 -0
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/setup.cfg +1 -1
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/setup.py +17 -1
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/tests/test_auth.py +3 -3
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/tests/test_errors.py +13 -13
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/tests/test_files_cp.py +1 -1
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/tests/test_invalid_secrets.py +1 -1
- ellf_cli-4.0.3/tests/test_login.py +242 -0
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/tests/test_recipes.py +1 -1
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/tests/test_support.py +282 -5
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/tests/test_ui_extras.py +8 -8
- ellf_cli-3.1.3/ellf_cli/recipes_cookiecutter/{{cookiecutter.package_dir}}/requirements.in +0 -1
- ellf_cli-3.1.3/ellf_cli/recipes_cookiecutter/{{cookiecutter.package_dir}}/{{cookiecutter.package_name}}/__init__.py +0 -0
- ellf_cli-3.1.3/tests/test_login.py +0 -109
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/LICENSE +0 -0
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/MANIFEST.in +0 -0
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli/__init__.py +0 -0
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli/__main__.py +0 -0
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli/about.py +0 -0
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli/appdirs.py +0 -0
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli/cloud/__init__.py +0 -0
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli/cluster_config.py +0 -0
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli/commands/__init__.py +0 -0
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli/commands/_state.py +0 -0
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli/commands/config.py +0 -0
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli/commands/files/__init__.py +0 -0
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli/commands/infra/__init__.py +0 -0
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli/commands/infra/provision.py +0 -0
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli/commands/infra/setup.py +0 -0
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli/commands/infra/terraform.py +0 -0
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli/commands/plans.py +0 -0
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli/config.py +0 -0
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli/key_pair.py +0 -0
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli/main.py +0 -0
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli/recipes_cookiecutter/cookiecutter.json +0 -0
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli/recipes_cookiecutter/{{cookiecutter.package_dir}}/.gitignore +0 -0
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli/recipes_cookiecutter/{{cookiecutter.package_dir}}/README.md.tmpl +0 -0
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli/recipes_cookiecutter/{{cookiecutter.package_dir}}/requirements-dev.in +0 -0
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli/recipes_cookiecutter/{{cookiecutter.package_dir}}/setup.py.tmpl +0 -0
- {ellf_cli-3.1.3/ellf_cli/recipes_cookiecutter/{{cookiecutter.package_dir}}/tests → ellf_cli-4.0.3/ellf_cli/recipes_cookiecutter/{{cookiecutter.package_dir}}/{{cookiecutter.package_name}}}/__init__.py +0 -0
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli/recipes_cookiecutter/{{cookiecutter.package_dir}}/{{cookiecutter.package_name}}/about.py +0 -0
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli/recipes_cookiecutter/{{cookiecutter.package_dir}}/{{cookiecutter.package_name}}/recipes/__init__.py +0 -0
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli/testing/__init__.py +0 -0
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli/ty.py +0 -0
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli/url.py +0 -0
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli.egg-info/dependency_links.txt +0 -0
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli.egg-info/entry_points.txt +0 -0
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli.egg-info/not-zip-safe +0 -0
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/ellf_cli.egg-info/top_level.txt +0 -0
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/tests/test_appdirs.py +0 -0
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/tests/test_config.py +0 -0
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/tests/test_files_cp_helpers.py +0 -0
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/tests/test_info.py +0 -0
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/tests/test_key_pair.py +0 -0
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/tests/test_main.py +0 -0
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/tests/test_projects.py +0 -0
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/tests/test_query.py +0 -0
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/tests/test_recipe_file.py +0 -0
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/tests/test_state.py +0 -0
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/tests/test_ty.py +0 -0
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/tests/test_ui.py +0 -0
- {ellf_cli-3.1.3 → ellf_cli-4.0.3}/tests/test_util.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ellf-cli
|
|
3
|
-
Version:
|
|
3
|
+
Version: 4.0.3
|
|
4
4
|
Summary: Ellf Command Line Interface
|
|
5
5
|
Home-page: https://prodi.gy
|
|
6
6
|
Author: ExplosionAI GmbH
|
|
@@ -13,8 +13,8 @@ Requires-Dist: httpx
|
|
|
13
13
|
Requires-Dist: httpx
|
|
14
14
|
Requires-Dist: packaging
|
|
15
15
|
Requires-Dist: pkginfo>=1.7
|
|
16
|
-
Requires-Dist:
|
|
17
|
-
Requires-Dist:
|
|
16
|
+
Requires-Dist: ellf-broker-sdk
|
|
17
|
+
Requires-Dist: ellf-pam-sdk
|
|
18
18
|
Requires-Dist: pydantic[email]>=2.0.0
|
|
19
19
|
Requires-Dist: pyjwt
|
|
20
20
|
Requires-Dist: radicli>=0.0.25
|
|
@@ -395,8 +395,8 @@ Rotate the broker RSA keypair. Generates a new keypair, updates the broker recor
|
|
|
395
395
|
| Argument | Type | Description | Default |
|
|
396
396
|
| --- | --- | --- | --- |
|
|
397
397
|
| `--cluster` | `str` | Name or ID of the cluster | `None` |
|
|
398
|
-
| `--infra-secret` | `str` | Name of the K8s secret holding
|
|
399
|
-
| `--namespace` | `str` | K8s namespace | `'
|
|
398
|
+
| `--infra-secret` | `str` | Name of the K8s secret holding ELLF_PRIVATE_KEY | `'ellf-infra'` |
|
|
399
|
+
| `--namespace` | `str` | K8s namespace | `'ellf'` |
|
|
400
400
|
|
|
401
401
|
#### `ellf clusters settings`
|
|
402
402
|
|
|
@@ -1022,7 +1022,7 @@ Upload and advertise a recipes package from your Python environment.
|
|
|
1022
1022
|
|
|
1023
1023
|
#### `ellf publish data`
|
|
1024
1024
|
|
|
1025
|
-
Transfer data to the cluster, and advertise it to
|
|
1025
|
+
Transfer data to the cluster, and advertise it to Ellf. These steps can also be done separately. See `ellf files` to transfer data to the cluster without creating an Asset record for it, and `ellf assets create` to create an Asset without transfer.
|
|
1026
1026
|
|
|
1027
1027
|
| Argument | Type | Description | Default |
|
|
1028
1028
|
| --- | --- | --- | --- |
|
|
@@ -1037,14 +1037,14 @@ Transfer data to the cluster, and advertise it to Prodigy Teams. These steps can
|
|
|
1037
1037
|
|
|
1038
1038
|
### `ellf login`
|
|
1039
1039
|
|
|
1040
|
-
Log in to your
|
|
1040
|
+
Log in to your Ellf account. You normally don't need to call this manually. It will automatically authenticate when needed.
|
|
1041
1041
|
|
|
1042
1042
|
| Argument | Type | Description | Default |
|
|
1043
1043
|
| --- | --- | --- | --- |
|
|
1044
1044
|
| `--no-cluster` | `bool` | Don't use a cluster | `False` |
|
|
1045
1045
|
| `--no-browser` | `bool` | Don't open a browser, just print the login URL | `False` |
|
|
1046
1046
|
| `--json` | `bool` | Output the result as JSON | `False` |
|
|
1047
|
-
| `--claude` | `bool` | Install Ellf Claude Code skills
|
|
1047
|
+
| `--claude` | `bool` | Install Ellf Claude Code skills and transcript hook into ~/.claude/ | `False` |
|
|
1048
1048
|
|
|
1049
1049
|
### `ellf info`
|
|
1050
1050
|
|
|
@@ -1100,7 +1100,7 @@ Deploy or upgrade the Ellf Helm chart. Creates the namespace, image pull secret,
|
|
|
1100
1100
|
| `--values` | `Path` | Path to values.yaml for Helm deployment | |
|
|
1101
1101
|
| `--chart` | `Path` | Path to local chart directory (default: OCI chart from registry) | `None` |
|
|
1102
1102
|
| `--latest` | `bool` | Fetch and use the latest image tags before deploying | `False` |
|
|
1103
|
-
| `--namespace` | `str` | Kubernetes namespace | `'
|
|
1103
|
+
| `--namespace` | `str` | Kubernetes namespace | `'ellf'` |
|
|
1104
1104
|
| `--wait` | `bool` | Wait for pods to be ready after deploying | `False` |
|
|
1105
1105
|
|
|
1106
1106
|
#### `ellf infra init-values`
|
|
@@ -1189,10 +1189,11 @@ Send a support request to the Ellf team.
|
|
|
1189
1189
|
| Argument | Type | Description | Default |
|
|
1190
1190
|
| --- | --- | --- | --- |
|
|
1191
1191
|
| `--message` | `str` | The user's support request or issue description | |
|
|
1192
|
-
| `--summary` | `str` |
|
|
1192
|
+
| `--summary` | `str` | Optional support-ready summary of the issue and current state | `None` |
|
|
1193
1193
|
| `--project` | `UUID` | ID of support request's project (or the last project if not set) | `None` |
|
|
1194
1194
|
| `--no-project` | `bool` | Explicitly send the request without any project association | `False` |
|
|
1195
1195
|
| `--conversation` | `UUID` | Conversation ID to attach from PAM when available | `None` |
|
|
1196
1196
|
| `--session-id` | `str` | Claude Code session ID to use for transcript/debug attachment lookup | `None` |
|
|
1197
|
+
| `--transcript-path` | `str` | Path to a Claude transcript .jsonl file to attach explicitly | `None` |
|
|
1197
1198
|
| `--transcript-consent` | `str` | Explicit transcript consent mode: 'summary_only' or 'attach_full_transcript' | `'summary_only'` |
|
|
1198
1199
|
| `--json` | `bool` | Output the result as JSON | `False` |
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"title": "Ellf CLI",
|
|
3
3
|
"name": "ellf-cli",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "4.0.3",
|
|
5
5
|
"summary": "Ellf Command Line Interface",
|
|
6
6
|
"uri": "https://prodi.gy",
|
|
7
7
|
"prog": "ellf",
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
"ellf.json"
|
|
15
15
|
],
|
|
16
16
|
"package_data_dirs": [
|
|
17
|
-
"recipes_cookiecutter"
|
|
17
|
+
"recipes_cookiecutter",
|
|
18
|
+
"ellf_skills"
|
|
18
19
|
]
|
|
19
20
|
}
|
|
@@ -12,20 +12,20 @@ import jwt
|
|
|
12
12
|
import pydantic
|
|
13
13
|
from pydantic import BaseModel, field_validator
|
|
14
14
|
|
|
15
|
-
from
|
|
15
|
+
from ellf_broker_sdk import (
|
|
16
16
|
AccessTokenCredential as BrokerAccessTokenCredential,
|
|
17
17
|
)
|
|
18
|
-
from
|
|
19
|
-
from
|
|
20
|
-
from
|
|
18
|
+
from ellf_broker_sdk import Client as BrokerClient
|
|
19
|
+
from ellf_pam_sdk import AccessTokenCredential, Client
|
|
20
|
+
from ellf_pam_sdk.models import BrokerReading
|
|
21
21
|
|
|
22
22
|
from .config import RootConfig
|
|
23
23
|
from .errors import (
|
|
24
24
|
CLIError,
|
|
25
|
+
EllfError,
|
|
26
|
+
EllfIDTokenError,
|
|
27
|
+
EllfParseSecretsError,
|
|
25
28
|
HTTPError,
|
|
26
|
-
ProdigyTeamsError,
|
|
27
|
-
ProdigyTeamsIDTokenError,
|
|
28
|
-
ProdigyTeamsParseSecretsError,
|
|
29
29
|
)
|
|
30
30
|
from .messages import Messages
|
|
31
31
|
from .ui import print_login_info
|
|
@@ -102,7 +102,7 @@ class FileSecrets(BaseModel):
|
|
|
102
102
|
try:
|
|
103
103
|
return cls.model_validate_json(path.read_text())
|
|
104
104
|
except pydantic.ValidationError as e:
|
|
105
|
-
raise
|
|
105
|
+
raise EllfParseSecretsError(secrets_file=path, error=e) from e
|
|
106
106
|
except FileNotFoundError:
|
|
107
107
|
return cls()
|
|
108
108
|
|
|
@@ -254,7 +254,7 @@ class AuthStateImpl:
|
|
|
254
254
|
# own org accessible
|
|
255
255
|
orgs = list(self.client.org.all())
|
|
256
256
|
if not orgs:
|
|
257
|
-
raise
|
|
257
|
+
raise EllfError(message="Could not fetch orgs")
|
|
258
258
|
self._org_id = orgs[0].id
|
|
259
259
|
return self._org_id
|
|
260
260
|
|
|
@@ -280,11 +280,11 @@ class AuthStateImpl:
|
|
|
280
280
|
def wrapper(*args: _P.args, **kwargs: _P.kwargs) -> _R:
|
|
281
281
|
try:
|
|
282
282
|
return func(*args, **kwargs)
|
|
283
|
-
except
|
|
283
|
+
except EllfIDTokenError:
|
|
284
284
|
self.get_id_token(force_refresh=True)
|
|
285
285
|
try:
|
|
286
286
|
return func(*args, **kwargs)
|
|
287
|
-
except (HTTPError,
|
|
287
|
+
except (HTTPError, EllfError) as e:
|
|
288
288
|
logger.exception(e)
|
|
289
289
|
raise CLIError(Messages.E104, e)
|
|
290
290
|
|
|
@@ -298,7 +298,7 @@ class AuthStateImpl:
|
|
|
298
298
|
self.get_api_token(force_refresh=True)
|
|
299
299
|
try:
|
|
300
300
|
return func(*args, **kwargs)
|
|
301
|
-
except (HTTPError,
|
|
301
|
+
except (HTTPError, EllfError) as e:
|
|
302
302
|
logger.exception(e)
|
|
303
303
|
raise CLIError(Messages.E105, e)
|
|
304
304
|
|
|
@@ -317,7 +317,7 @@ class AuthStateImpl:
|
|
|
317
317
|
self._secrets = None
|
|
318
318
|
try:
|
|
319
319
|
self.secrets
|
|
320
|
-
except
|
|
320
|
+
except EllfParseSecretsError:
|
|
321
321
|
FileSecrets.clean(self._secrets_path)
|
|
322
322
|
return self.secrets
|
|
323
323
|
|
|
@@ -385,7 +385,7 @@ class AuthStateImpl:
|
|
|
385
385
|
)
|
|
386
386
|
if api_response.status_code != 200:
|
|
387
387
|
err = _format_http_error(api_response)
|
|
388
|
-
raise
|
|
388
|
+
raise EllfIDTokenError(err)
|
|
389
389
|
data = api_response.json()
|
|
390
390
|
token = AccessTokenCredential(access_token=data["access_token"])
|
|
391
391
|
self.secrets.api_token = token
|
|
@@ -415,8 +415,8 @@ class AuthStateImpl:
|
|
|
415
415
|
if res.status_code != 200:
|
|
416
416
|
err = _format_http_error(res)
|
|
417
417
|
if res.status_code == 401:
|
|
418
|
-
raise
|
|
419
|
-
raise
|
|
418
|
+
raise EllfIDTokenError(err)
|
|
419
|
+
raise EllfError(err)
|
|
420
420
|
data = res.json()
|
|
421
421
|
pam_broker_token = data["access_token"]
|
|
422
422
|
# Exchange the PAM-issued broker-scoped token at the broker's
|
|
@@ -429,8 +429,8 @@ class AuthStateImpl:
|
|
|
429
429
|
if exchange_res.status_code != 200:
|
|
430
430
|
err = _format_http_error(exchange_res)
|
|
431
431
|
if exchange_res.status_code == 401:
|
|
432
|
-
raise
|
|
433
|
-
raise
|
|
432
|
+
raise EllfIDTokenError(err)
|
|
433
|
+
raise EllfError(err)
|
|
434
434
|
exchange_data = exchange_res.json()
|
|
435
435
|
token = BrokerAccessTokenCredential(
|
|
436
436
|
access_token=exchange_data["access_token"]
|
|
@@ -449,7 +449,7 @@ class AuthStateImpl:
|
|
|
449
449
|
except httpx.HTTPError as exc:
|
|
450
450
|
err = Messages.E033.format(url=self.pam_url)
|
|
451
451
|
logger.exception(err)
|
|
452
|
-
raise
|
|
452
|
+
raise EllfError(err) from exc
|
|
453
453
|
device_code_url = str(self.pam_url / "api/v1/device/code")
|
|
454
454
|
token_url = str(self.pam_url / "api/v1/device/token")
|
|
455
455
|
response = httpx.post(device_code_url, json={"scope": OIDC_SCOPE})
|
|
@@ -480,9 +480,9 @@ class AuthStateImpl:
|
|
|
480
480
|
if token_response.status_code == 200:
|
|
481
481
|
id_token = token_data.get("id_token")
|
|
482
482
|
if id_token is None:
|
|
483
|
-
raise
|
|
483
|
+
raise EllfIDTokenError(
|
|
484
484
|
"Device auth succeeded but no id_token in response"
|
|
485
485
|
)
|
|
486
486
|
return id_token
|
|
487
487
|
time.sleep(1)
|
|
488
|
-
raise
|
|
488
|
+
raise EllfIDTokenError(Messages.E031)
|
|
@@ -8,11 +8,11 @@ from typing import Any
|
|
|
8
8
|
from radicli import Radicli, get_list_converter
|
|
9
9
|
from wasabi import msg
|
|
10
10
|
|
|
11
|
-
from
|
|
12
|
-
from
|
|
11
|
+
from ellf_broker_sdk.errors import BrokerError
|
|
12
|
+
from ellf_pam_sdk.errors import AuthError, RecipeProcessingError
|
|
13
13
|
|
|
14
14
|
from . import about
|
|
15
|
-
from .errors import CLIError, HTTPError, HTTPStatusError, HTTPXErrors
|
|
15
|
+
from .errors import CLIError, EllfError, HTTPError, HTTPStatusError, HTTPXErrors
|
|
16
16
|
from .messages import Messages
|
|
17
17
|
from .ui import isatty
|
|
18
18
|
|
|
@@ -34,7 +34,7 @@ def handle_cli_error(err: CLIError | RecipeProcessingError) -> int:
|
|
|
34
34
|
return _emit_error(str(err.title), str(err.text) if err.text else None)
|
|
35
35
|
|
|
36
36
|
|
|
37
|
-
def handle_teams_error(err:
|
|
37
|
+
def handle_teams_error(err: EllfError) -> int:
|
|
38
38
|
return _emit_error(str(err.message))
|
|
39
39
|
|
|
40
40
|
|
|
@@ -82,7 +82,7 @@ CONVERTERS: dict[Any, Any] = {list[str]: get_list_converter(str)}
|
|
|
82
82
|
ERRORS = {
|
|
83
83
|
CLIError: handle_cli_error,
|
|
84
84
|
RecipeProcessingError: handle_cli_error,
|
|
85
|
-
|
|
85
|
+
EllfError: handle_teams_error,
|
|
86
86
|
BrokerError: handle_broker_error,
|
|
87
87
|
**{error: handle_http_error for error in HTTPXErrors},
|
|
88
88
|
}
|
|
@@ -44,7 +44,7 @@ def create_project(
|
|
|
44
44
|
project_id: str, project_name: Optional[str] = None, exist_ok=False
|
|
45
45
|
) -> str:
|
|
46
46
|
"""
|
|
47
|
-
Create a Google Cloud project to use to deploy a
|
|
47
|
+
Create a Google Cloud project to use to deploy a Ellf cluster. \
|
|
48
48
|
"""
|
|
49
49
|
check_gcloud_exists()
|
|
50
50
|
if project_name is None:
|
|
@@ -84,7 +84,7 @@ def create_service_account(
|
|
|
84
84
|
project_name: str, service_account_name: str, display_name: str, exist_ok=True
|
|
85
85
|
) -> str:
|
|
86
86
|
"""
|
|
87
|
-
Create a service account that will be used to deploy the
|
|
87
|
+
Create a service account that will be used to deploy the Ellf cluster. \
|
|
88
88
|
Included in the init sub-command.
|
|
89
89
|
"""
|
|
90
90
|
check_gcloud_exists()
|
|
@@ -136,7 +136,7 @@ def add_service_account_member(project_name: str, service_account_name: str):
|
|
|
136
136
|
Included in the init sub-command.
|
|
137
137
|
|
|
138
138
|
This is needed to be able use the service account to deploy the \
|
|
139
|
-
|
|
139
|
+
Ellf cluster.
|
|
140
140
|
"""
|
|
141
141
|
check_gcloud_exists()
|
|
142
142
|
msg.info(
|
|
@@ -235,7 +235,7 @@ def setup_billing(project_name: str) -> None:
|
|
|
235
235
|
|
|
236
236
|
def enable_apis(project_name: str) -> None:
|
|
237
237
|
"""
|
|
238
|
-
Enable the required Google Cloud APIs to deploy the
|
|
238
|
+
Enable the required Google Cloud APIs to deploy the Ellf cluster. \
|
|
239
239
|
Included in the init sub-command.
|
|
240
240
|
"""
|
|
241
241
|
check_gcloud_exists()
|
|
@@ -15,10 +15,10 @@ from radicli import (
|
|
|
15
15
|
)
|
|
16
16
|
from wasabi import msg
|
|
17
17
|
|
|
18
|
-
from
|
|
19
|
-
from
|
|
20
|
-
from
|
|
21
|
-
from
|
|
18
|
+
from ellf_broker_sdk import models as broker_models
|
|
19
|
+
from ellf_broker_sdk.models import JobID, JobType
|
|
20
|
+
from ellf_pam_sdk import Client
|
|
21
|
+
from ellf_pam_sdk.models import (
|
|
22
22
|
ActionCreating,
|
|
23
23
|
AgentCreating,
|
|
24
24
|
ObjectValidation,
|
|
@@ -27,7 +27,7 @@ from prodigy_teams_pam_sdk.models import (
|
|
|
27
27
|
RecipePlanCreating,
|
|
28
28
|
TaskCreating,
|
|
29
29
|
)
|
|
30
|
-
from
|
|
30
|
+
from ellf_pam_sdk.recipe_utils import (
|
|
31
31
|
Field,
|
|
32
32
|
RecipeSchema,
|
|
33
33
|
get_field_cli_args,
|
|
@@ -38,7 +38,7 @@ from prodigy_teams_pam_sdk.recipe_utils import (
|
|
|
38
38
|
from ..auth import AuthState
|
|
39
39
|
from ..cli import CONVERTERS, cli
|
|
40
40
|
from ..config import SavedSettings
|
|
41
|
-
from ..errors import CLIError,
|
|
41
|
+
from ..errors import CLIError, EllfErrors
|
|
42
42
|
from ..messages import Messages
|
|
43
43
|
from ..query import resolve_project_id
|
|
44
44
|
from ..ui import RecipeHelpFormatter, get_recipe_desc
|
|
@@ -63,8 +63,8 @@ def request_recipes(
|
|
|
63
63
|
is_action: bool | None = None,
|
|
64
64
|
job_type: str | None = None,
|
|
65
65
|
) -> dict[str, RecipeDetail]:
|
|
66
|
-
"""Fetch all Recipes from
|
|
67
|
-
auth (AuthState): CLI Auth object to handle auth to the
|
|
66
|
+
"""Fetch all Recipes from Ellf or a local recipes file.
|
|
67
|
+
auth (AuthState): CLI Auth object to handle auth to the Ellf API
|
|
68
68
|
RETURNS (Dict[str, RecipeDetail]): Recipe schemas keyed by name
|
|
69
69
|
"""
|
|
70
70
|
from pathlib import Path
|
|
@@ -312,17 +312,17 @@ def _create_task(
|
|
|
312
312
|
body = TaskCreating(name=name, project_id=project_id, plan=plan)
|
|
313
313
|
try:
|
|
314
314
|
task = client.task.create(body)
|
|
315
|
-
except
|
|
315
|
+
except EllfErrors.ProjectNotFound:
|
|
316
316
|
err = Messages.E013.format(name=project_id)
|
|
317
317
|
raise CLIError(err)
|
|
318
|
-
except
|
|
318
|
+
except EllfErrors.TaskExists:
|
|
319
319
|
if exists_ok:
|
|
320
320
|
msg.info(Messages.T001.format(noun="task", name=name))
|
|
321
321
|
task = client.task.read(name=name, project_id=project_id)
|
|
322
322
|
return JobID(id=task.id, job_type=JobType.task)
|
|
323
323
|
err = Messages.E014.format(noun="task", name=name, project=project_id)
|
|
324
324
|
raise CLIError(err)
|
|
325
|
-
except
|
|
325
|
+
except EllfErrors.TaskInvalid:
|
|
326
326
|
raise CLIError(Messages.E004.format(noun="task", name=name))
|
|
327
327
|
return JobID(id=task.id, job_type=JobType.task)
|
|
328
328
|
|
|
@@ -337,17 +337,17 @@ def _create_action(
|
|
|
337
337
|
body = ActionCreating(name=name, project_id=project_id, evaluation="", plan=plan)
|
|
338
338
|
try:
|
|
339
339
|
action = client.action.create(body)
|
|
340
|
-
except
|
|
340
|
+
except EllfErrors.ProjectNotFound:
|
|
341
341
|
err = Messages.E013.format(name=project_id)
|
|
342
342
|
raise CLIError(err)
|
|
343
|
-
except
|
|
343
|
+
except EllfErrors.ActionExists:
|
|
344
344
|
if exists_ok:
|
|
345
345
|
msg.info(Messages.T001.format(noun="action", name=name))
|
|
346
346
|
action = client.action.read(name=name, project_id=project_id)
|
|
347
347
|
return JobID(id=action.id, job_type=JobType.action)
|
|
348
348
|
err = Messages.E014.format(noun="action", name=name, project=project_id)
|
|
349
349
|
raise CLIError(err)
|
|
350
|
-
except
|
|
350
|
+
except EllfErrors.ActionInvalid:
|
|
351
351
|
raise CLIError(Messages.E004.format(noun="action", name=name))
|
|
352
352
|
return JobID(id=action.id, job_type=JobType.action)
|
|
353
353
|
|
|
@@ -362,17 +362,17 @@ def _create_agent(
|
|
|
362
362
|
body = AgentCreating(name=name, project_id=project_id, plan=plan)
|
|
363
363
|
try:
|
|
364
364
|
agent = client.agent.create(body)
|
|
365
|
-
except
|
|
365
|
+
except EllfErrors.ProjectNotFound:
|
|
366
366
|
err = Messages.E013.format(name=project_id)
|
|
367
367
|
raise CLIError(err)
|
|
368
|
-
except
|
|
368
|
+
except EllfErrors.AgentExists:
|
|
369
369
|
if exists_ok:
|
|
370
370
|
msg.info(Messages.T001.format(noun="agent", name=name))
|
|
371
371
|
agent = client.agent.read(name=name, project_id=project_id)
|
|
372
372
|
return JobID(id=agent.id, job_type=JobType.agent)
|
|
373
373
|
err = Messages.E014.format(noun="agent", name=name, project=project_id)
|
|
374
374
|
raise CLIError(err)
|
|
375
|
-
except
|
|
375
|
+
except EllfErrors.AgentInvalid:
|
|
376
376
|
raise CLIError(Messages.E004.format(noun="agent", name=name))
|
|
377
377
|
return JobID(id=agent.id, job_type=JobType.agent)
|
|
378
378
|
|
|
@@ -6,10 +6,10 @@ from uuid import UUID
|
|
|
6
6
|
from radicli import Arg
|
|
7
7
|
from wasabi import msg
|
|
8
8
|
|
|
9
|
-
from
|
|
9
|
+
from ellf_pam_sdk.models import ActionDetail, ActionSummary
|
|
10
10
|
|
|
11
11
|
from ..cli import cli
|
|
12
|
-
from ..errors import BrokerError, CLIError,
|
|
12
|
+
from ..errors import BrokerError, CLIError, EllfError, HTTPXErrors
|
|
13
13
|
from ..messages import Messages
|
|
14
14
|
from ..query import delete_job, resolve_action, resolve_recipe, start_job, stop_job
|
|
15
15
|
from ..ui import (
|
|
@@ -54,7 +54,7 @@ def create(
|
|
|
54
54
|
is_file_mode = settings.recipes_file is not None
|
|
55
55
|
try:
|
|
56
56
|
action_schemas = request_recipes(auth=auth, is_action=True)
|
|
57
|
-
except
|
|
57
|
+
except EllfError as e:
|
|
58
58
|
raise CLIError(Messages.E009, e)
|
|
59
59
|
except HTTPXErrors as e:
|
|
60
60
|
raise CLIError(Messages.E009, e)
|
|
@@ -6,10 +6,10 @@ from uuid import UUID
|
|
|
6
6
|
from radicli import Arg
|
|
7
7
|
from wasabi import msg
|
|
8
8
|
|
|
9
|
-
from
|
|
9
|
+
from ellf_pam_sdk.models import AgentDetail, AgentSummary
|
|
10
10
|
|
|
11
11
|
from ..cli import cli
|
|
12
|
-
from ..errors import BrokerError, CLIError,
|
|
12
|
+
from ..errors import BrokerError, CLIError, EllfError, HTTPXErrors
|
|
13
13
|
from ..messages import Messages
|
|
14
14
|
from ..query import (
|
|
15
15
|
delete_job,
|
|
@@ -61,7 +61,7 @@ def create(
|
|
|
61
61
|
is_file_mode = settings.recipes_file is not None
|
|
62
62
|
try:
|
|
63
63
|
schemas = request_recipes(auth=auth, job_type="agent")
|
|
64
|
-
except
|
|
64
|
+
except EllfError as e:
|
|
65
65
|
raise CLIError(Messages.E009, e)
|
|
66
66
|
except HTTPXErrors as e:
|
|
67
67
|
raise CLIError(Messages.E009, e)
|
|
@@ -7,10 +7,10 @@ from uuid import UUID
|
|
|
7
7
|
from radicli.util import Arg
|
|
8
8
|
from wasabi import msg
|
|
9
9
|
|
|
10
|
-
from
|
|
10
|
+
from ellf_pam_sdk.models import AssetCreating, AssetDetail, AssetSummary
|
|
11
11
|
|
|
12
12
|
from ..cli import cli
|
|
13
|
-
from ..errors import CLIError,
|
|
13
|
+
from ..errors import CLIError, EllfErrors
|
|
14
14
|
from ..messages import Messages
|
|
15
15
|
from ..query import resolve_asset, resolve_asset_id
|
|
16
16
|
from ..ui import print_info_table, print_mutation_result, print_table_with_select
|
|
@@ -111,7 +111,7 @@ def create(
|
|
|
111
111
|
path=resolved_path,
|
|
112
112
|
)
|
|
113
113
|
)
|
|
114
|
-
except
|
|
114
|
+
except EllfErrors.AssetExists:
|
|
115
115
|
if exists_ok:
|
|
116
116
|
msg.info(Messages.T001.format(noun="asset", name=name))
|
|
117
117
|
return None
|
|
@@ -144,9 +144,9 @@ def delete(
|
|
|
144
144
|
auth = get_auth_state()
|
|
145
145
|
try:
|
|
146
146
|
auth.client.asset.delete(id=asset_id)
|
|
147
|
-
except
|
|
147
|
+
except EllfErrors.AssetNotFound:
|
|
148
148
|
raise CLIError(Messages.E006.format(noun="asset", name=name_or_id))
|
|
149
|
-
except
|
|
149
|
+
except EllfErrors.AssetForbiddenDelete:
|
|
150
150
|
raise CLIError(Messages.E007.format(noun="asset", name=name_or_id))
|
|
151
151
|
else:
|
|
152
152
|
print_mutation_result(
|
|
@@ -10,8 +10,8 @@ import uuid_utils
|
|
|
10
10
|
from radicli import Arg
|
|
11
11
|
from wasabi import msg
|
|
12
12
|
|
|
13
|
-
from
|
|
14
|
-
from
|
|
13
|
+
from ellf_pam_sdk import models as ellf_pam_sdk_models
|
|
14
|
+
from ellf_pam_sdk.models import (
|
|
15
15
|
BrokerUpdating,
|
|
16
16
|
)
|
|
17
17
|
|
|
@@ -36,12 +36,12 @@ def uuid7() -> uuid.UUID:
|
|
|
36
36
|
return uuid.UUID(int=uuid_utils.uuid7().int)
|
|
37
37
|
|
|
38
38
|
|
|
39
|
-
DEFAULT_NAMESPACE = "
|
|
40
|
-
DEFAULT_RELEASE = "
|
|
39
|
+
DEFAULT_NAMESPACE = "ellf"
|
|
40
|
+
DEFAULT_RELEASE = "ellf"
|
|
41
41
|
|
|
42
42
|
|
|
43
43
|
def check_broker_status(
|
|
44
|
-
broker:
|
|
44
|
+
broker: ellf_pam_sdk_models.BrokerSummary,
|
|
45
45
|
) -> BrokerStatusCheck:
|
|
46
46
|
url = URL.parse(broker.address) / "api/v1/status"
|
|
47
47
|
# Before querying the broker, verify that it has finished registration
|
|
@@ -71,7 +71,7 @@ def check_broker_status(
|
|
|
71
71
|
return BrokerStatusCheck.RESPONSE_ERROR
|
|
72
72
|
|
|
73
73
|
|
|
74
|
-
class BrokerSummary(
|
|
74
|
+
class BrokerSummary(ellf_pam_sdk_models.BrokerSummary):
|
|
75
75
|
"""
|
|
76
76
|
Extends the data returned by the API with computed properties.
|
|
77
77
|
This is a workaround for the models being auto-generated.
|
|
@@ -102,7 +102,7 @@ class BrokerSummary(prodigy_teams_pam_sdk_models.BrokerSummary):
|
|
|
102
102
|
return data
|
|
103
103
|
|
|
104
104
|
|
|
105
|
-
class BrokerDetail(BrokerSummary,
|
|
105
|
+
class BrokerDetail(BrokerSummary, ellf_pam_sdk_models.BrokerDetail):
|
|
106
106
|
pass
|
|
107
107
|
|
|
108
108
|
|
|
@@ -339,14 +339,14 @@ def nodes(
|
|
|
339
339
|
name_or_id=Arg("--cluster", help=Messages.name_or_id.format(noun="cluster")),
|
|
340
340
|
infra_secret=Arg(
|
|
341
341
|
"--infra-secret",
|
|
342
|
-
help="Name of the K8s secret holding
|
|
342
|
+
help="Name of the K8s secret holding ELLF_PRIVATE_KEY",
|
|
343
343
|
),
|
|
344
344
|
namespace=Arg("--namespace", help="K8s namespace"),
|
|
345
345
|
)
|
|
346
346
|
def rotate_key(
|
|
347
347
|
name_or_id: Optional[Union[str, UUID]] = None,
|
|
348
|
-
infra_secret: str = "
|
|
349
|
-
namespace: str = "
|
|
348
|
+
infra_secret: str = "ellf-infra",
|
|
349
|
+
namespace: str = "ellf",
|
|
350
350
|
) -> None:
|
|
351
351
|
"""Rotate the broker RSA keypair.
|
|
352
352
|
|
|
@@ -398,8 +398,8 @@ def rotate_key(
|
|
|
398
398
|
"generic",
|
|
399
399
|
infra_secret,
|
|
400
400
|
f"--namespace={namespace}",
|
|
401
|
-
f"--from-literal=
|
|
402
|
-
f"--from-literal=
|
|
401
|
+
f"--from-literal=ELLF_PRIVATE_KEY={private_key_b64}",
|
|
402
|
+
f"--from-literal=ELLF_PUBLIC_KEY={public_key_b64}",
|
|
403
403
|
"--dry-run=client",
|
|
404
404
|
"-o",
|
|
405
405
|
"yaml",
|
|
@@ -419,7 +419,7 @@ def rotate_key(
|
|
|
419
419
|
"kubectl",
|
|
420
420
|
"rollout",
|
|
421
421
|
"restart",
|
|
422
|
-
"deployment/
|
|
422
|
+
"deployment/ellf-broker",
|
|
423
423
|
f"--namespace={namespace}",
|
|
424
424
|
],
|
|
425
425
|
check=True,
|
|
@@ -480,7 +480,7 @@ def settings_update(
|
|
|
480
480
|
as_json: bool = False,
|
|
481
481
|
) -> None:
|
|
482
482
|
"""Update cluster settings."""
|
|
483
|
-
from
|
|
483
|
+
from ellf_pam_sdk.models import ClusterSettingsUpdating
|
|
484
484
|
|
|
485
485
|
auth = get_auth_state()
|
|
486
486
|
broker_id = resolve_broker_id(name_or_id)
|
|
@@ -8,10 +8,10 @@ import srsly
|
|
|
8
8
|
from radicli import Arg
|
|
9
9
|
from wasabi import msg
|
|
10
10
|
|
|
11
|
-
from
|
|
11
|
+
from ellf_pam_sdk.models import DatasetDetail, DatasetSummary
|
|
12
12
|
|
|
13
13
|
from ..cli import cli
|
|
14
|
-
from ..errors import CLIError,
|
|
14
|
+
from ..errors import CLIError, EllfErrors
|
|
15
15
|
from ..messages import Messages
|
|
16
16
|
from ..query import collect_from_pages, resolve_dataset, resolve_dataset_id
|
|
17
17
|
from ..ui import (
|
|
@@ -84,14 +84,14 @@ def create(
|
|
|
84
84
|
broker_id = auth.broker_id
|
|
85
85
|
try:
|
|
86
86
|
res = client.dataset.create(name=name, kind=kind, broker_id=broker_id)
|
|
87
|
-
except
|
|
87
|
+
except EllfErrors.DatasetExists:
|
|
88
88
|
if exists_ok:
|
|
89
89
|
msg.info(Messages.T001.format(noun="dataset", name=name))
|
|
90
90
|
return None
|
|
91
91
|
raise CLIError(Messages.E002.format(noun="dataset", name=name))
|
|
92
|
-
except
|
|
92
|
+
except EllfErrors.DatasetInvalid:
|
|
93
93
|
raise CLIError(Messages.E004.format(noun="dataset", name=name))
|
|
94
|
-
except
|
|
94
|
+
except EllfErrors.DatasetForbiddenCreate:
|
|
95
95
|
raise CLIError(Messages.E003.format(noun="dataset", name=name))
|
|
96
96
|
print_mutation_result(
|
|
97
97
|
{"id": str(res.id), "name": res.name},
|
|
@@ -121,8 +121,8 @@ def delete(
|
|
|
121
121
|
try:
|
|
122
122
|
auth.client.dataset.delete(id=dataset_id)
|
|
123
123
|
except (
|
|
124
|
-
|
|
125
|
-
|
|
124
|
+
EllfErrors.ProjectForbiddenDelete,
|
|
125
|
+
EllfErrors.ProjectNotFound,
|
|
126
126
|
):
|
|
127
127
|
raise CLIError(Messages.E006.format(noun="dataset", name=name_or_id))
|
|
128
128
|
else:
|
|
@@ -6,8 +6,8 @@ from typing import Optional, Protocol
|
|
|
6
6
|
from radicli import Arg
|
|
7
7
|
from wasabi import msg
|
|
8
8
|
|
|
9
|
-
from
|
|
10
|
-
from
|
|
9
|
+
from ellf_broker_sdk import Client as BrokerClient
|
|
10
|
+
from ellf_broker_sdk import models as broker_models
|
|
11
11
|
|
|
12
12
|
from ...cli import cli
|
|
13
13
|
from ...errors import BrokerError, CLIError
|
|
@@ -2,8 +2,8 @@ from typing import Optional
|
|
|
2
2
|
|
|
3
3
|
from radicli import Arg
|
|
4
4
|
|
|
5
|
-
from
|
|
6
|
-
from
|
|
5
|
+
from ellf_broker_sdk import errors as broker_errors
|
|
6
|
+
from ellf_broker_sdk import models as broker_models
|
|
7
7
|
|
|
8
8
|
from ... import errors
|
|
9
9
|
from ...cli import cli
|