mirrorneuron-cli 1.1.1__tar.gz → 1.1.2__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.
- {mirrorneuron_cli-1.1.1 → mirrorneuron_cli-1.1.2}/.github/workflows/ci.yml +2 -2
- {mirrorneuron_cli-1.1.1 → mirrorneuron_cli-1.1.2}/.github/workflows/release.yml +2 -2
- {mirrorneuron_cli-1.1.1 → mirrorneuron_cli-1.1.2}/PKG-INFO +4 -4
- {mirrorneuron_cli-1.1.1 → mirrorneuron_cli-1.1.2}/README.md +2 -2
- {mirrorneuron_cli-1.1.1 → mirrorneuron_cli-1.1.2}/mirrorneuron_cli.egg-info/PKG-INFO +4 -4
- {mirrorneuron_cli-1.1.1 → mirrorneuron_cli-1.1.2}/mn_cli/error_handler.py +1 -2
- {mirrorneuron_cli-1.1.1 → mirrorneuron_cli-1.1.2}/mn_cli/libs/run_cmds.py +2 -5
- {mirrorneuron_cli-1.1.1 → mirrorneuron_cli-1.1.2}/mn_cli/libs/sys_cmds.py +0 -1
- {mirrorneuron_cli-1.1.1 → mirrorneuron_cli-1.1.2}/mn_cli/libs/ui.py +1 -1
- {mirrorneuron_cli-1.1.1 → mirrorneuron_cli-1.1.2}/mn_cli/update_cmds.py +1 -1
- {mirrorneuron_cli-1.1.1 → mirrorneuron_cli-1.1.2}/pyproject.toml +1 -1
- {mirrorneuron_cli-1.1.1 → mirrorneuron_cli-1.1.2}/tests/test_blueprint_cmds.py +0 -3
- {mirrorneuron_cli-1.1.1 → mirrorneuron_cli-1.1.2}/tests/test_job_cmds.py +0 -1
- {mirrorneuron_cli-1.1.1 → mirrorneuron_cli-1.1.2}/tests/test_run_cmds.py +7 -8
- {mirrorneuron_cli-1.1.1 → mirrorneuron_cli-1.1.2}/tests/test_server_cmds.py +1 -4
- {mirrorneuron_cli-1.1.1 → mirrorneuron_cli-1.1.2}/tests/test_sys_cmds.py +1 -4
- {mirrorneuron_cli-1.1.1 → mirrorneuron_cli-1.1.2}/.gitignore +0 -0
- {mirrorneuron_cli-1.1.1 → mirrorneuron_cli-1.1.2}/LICENSE +0 -0
- {mirrorneuron_cli-1.1.1 → mirrorneuron_cli-1.1.2}/RELEASE.md +0 -0
- {mirrorneuron_cli-1.1.1 → mirrorneuron_cli-1.1.2}/mirrorneuron_cli.egg-info/SOURCES.txt +0 -0
- {mirrorneuron_cli-1.1.1 → mirrorneuron_cli-1.1.2}/mirrorneuron_cli.egg-info/dependency_links.txt +0 -0
- {mirrorneuron_cli-1.1.1 → mirrorneuron_cli-1.1.2}/mirrorneuron_cli.egg-info/entry_points.txt +0 -0
- {mirrorneuron_cli-1.1.1 → mirrorneuron_cli-1.1.2}/mirrorneuron_cli.egg-info/requires.txt +0 -0
- {mirrorneuron_cli-1.1.1 → mirrorneuron_cli-1.1.2}/mirrorneuron_cli.egg-info/top_level.txt +0 -0
- {mirrorneuron_cli-1.1.1 → mirrorneuron_cli-1.1.2}/mn_cli/__init__.py +0 -0
- {mirrorneuron_cli-1.1.1 → mirrorneuron_cli-1.1.2}/mn_cli/config.py +0 -0
- {mirrorneuron_cli-1.1.1 → mirrorneuron_cli-1.1.2}/mn_cli/libs/__init__.py +0 -0
- {mirrorneuron_cli-1.1.1 → mirrorneuron_cli-1.1.2}/mn_cli/libs/blueprint_cmds.py +0 -0
- {mirrorneuron_cli-1.1.1 → mirrorneuron_cli-1.1.2}/mn_cli/libs/job_cmds.py +0 -0
- {mirrorneuron_cli-1.1.1 → mirrorneuron_cli-1.1.2}/mn_cli/logging_config.py +0 -0
- {mirrorneuron_cli-1.1.1 → mirrorneuron_cli-1.1.2}/mn_cli/main.py +0 -0
- {mirrorneuron_cli-1.1.1 → mirrorneuron_cli-1.1.2}/mn_cli/server_cmds.py +0 -0
- {mirrorneuron_cli-1.1.1 → mirrorneuron_cli-1.1.2}/mn_cli/shared.py +0 -0
- {mirrorneuron_cli-1.1.1 → mirrorneuron_cli-1.1.2}/scripts/check-release-artifacts.sh +0 -0
- {mirrorneuron_cli-1.1.1 → mirrorneuron_cli-1.1.2}/scripts/make-release-zip.sh +0 -0
- {mirrorneuron_cli-1.1.1 → mirrorneuron_cli-1.1.2}/scripts/validate-version-tag.sh +0 -0
- {mirrorneuron_cli-1.1.1 → mirrorneuron_cli-1.1.2}/setup.cfg +0 -0
- {mirrorneuron_cli-1.1.1 → mirrorneuron_cli-1.1.2}/tests/conftest.py +0 -0
- {mirrorneuron_cli-1.1.1 → mirrorneuron_cli-1.1.2}/tests/test_update_cmds.py +0 -0
|
@@ -64,7 +64,7 @@ jobs:
|
|
|
64
64
|
if: steps.detect.outputs.has_python_package == 'true' || steps.detect.outputs.has_python_tests == 'true'
|
|
65
65
|
uses: actions/setup-python@v5
|
|
66
66
|
with:
|
|
67
|
-
python-version: "3.
|
|
67
|
+
python-version: "3.11"
|
|
68
68
|
cache: pip
|
|
69
69
|
|
|
70
70
|
- name: Set up Node.js
|
|
@@ -96,7 +96,7 @@ jobs:
|
|
|
96
96
|
|
|
97
97
|
if [[ "$GITHUB_REPOSITORY" == "MirrorNeuronLab/mn-blueprints" ]]; then
|
|
98
98
|
python -m pip install "mirrorneuron-python-sdk @ git+https://github.com/MirrorNeuronLab/mn-python-sdk.git"
|
|
99
|
-
python -m pip install "mirrorneuron-blueprint-support-skill"
|
|
99
|
+
python -m pip install "mirrorneuron-blueprint-support-skill @ git+https://github.com/MirrorNeuronLab/mn-skills.git#subdirectory=blueprint_support_skill"
|
|
100
100
|
fi
|
|
101
101
|
|
|
102
102
|
if [[ "$GITHUB_REPOSITORY" == "MirrorNeuronLab/mn-system-tests" ]]; then
|
|
@@ -90,7 +90,7 @@ jobs:
|
|
|
90
90
|
if: steps.detect.outputs.has_python_package == 'true' || steps.detect.outputs.has_python_tests == 'true'
|
|
91
91
|
uses: actions/setup-python@v5
|
|
92
92
|
with:
|
|
93
|
-
python-version: "3.
|
|
93
|
+
python-version: "3.11"
|
|
94
94
|
cache: pip
|
|
95
95
|
|
|
96
96
|
- name: Set up Node.js
|
|
@@ -122,7 +122,7 @@ jobs:
|
|
|
122
122
|
|
|
123
123
|
if [[ "$GITHUB_REPOSITORY" == "MirrorNeuronLab/mn-blueprints" ]]; then
|
|
124
124
|
python -m pip install "mirrorneuron-python-sdk @ git+https://github.com/MirrorNeuronLab/mn-python-sdk.git"
|
|
125
|
-
python -m pip install "mirrorneuron-blueprint-support-skill"
|
|
125
|
+
python -m pip install "mirrorneuron-blueprint-support-skill @ git+https://github.com/MirrorNeuronLab/mn-skills.git#subdirectory=blueprint_support_skill"
|
|
126
126
|
fi
|
|
127
127
|
|
|
128
128
|
if [[ "$GITHUB_REPOSITORY" == "MirrorNeuronLab/mn-system-tests" ]]; then
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mirrorneuron-cli
|
|
3
|
-
Version: 1.1.
|
|
3
|
+
Version: 1.1.2
|
|
4
4
|
Summary: MirrorNeuron CLI
|
|
5
5
|
License-Expression: MIT
|
|
6
6
|
Classifier: Programming Language :: Python :: 3
|
|
7
|
-
Requires-Python: >=3.
|
|
7
|
+
Requires-Python: >=3.11
|
|
8
8
|
Description-Content-Type: text/markdown
|
|
9
9
|
License-File: LICENSE
|
|
10
10
|
Requires-Dist: mirrorneuron-python-sdk
|
|
@@ -31,7 +31,7 @@ The CLI submits workflow bundles, monitors jobs, manages the local runtime servi
|
|
|
31
31
|
|
|
32
32
|
| Area | Tooling |
|
|
33
33
|
| --- | --- |
|
|
34
|
-
| Runtime | Python 3.
|
|
34
|
+
| Runtime | Python 3.11+ |
|
|
35
35
|
| CLI framework | Typer |
|
|
36
36
|
| Terminal rendering | Rich |
|
|
37
37
|
| Core client | `mirrorneuron-python-sdk` |
|
|
@@ -39,7 +39,7 @@ The CLI submits workflow bundles, monitors jobs, manages the local runtime servi
|
|
|
39
39
|
|
|
40
40
|
## Prerequisites
|
|
41
41
|
|
|
42
|
-
- Python 3.
|
|
42
|
+
- Python 3.11 or newer.
|
|
43
43
|
- A MirrorNeuron core reachable over gRPC.
|
|
44
44
|
- Docker for the default local core and Redis workflow.
|
|
45
45
|
- Optional: the released-package installer from `mn-deploy`, which installs and wires the CLI automatically.
|
|
@@ -17,7 +17,7 @@ The CLI submits workflow bundles, monitors jobs, manages the local runtime servi
|
|
|
17
17
|
|
|
18
18
|
| Area | Tooling |
|
|
19
19
|
| --- | --- |
|
|
20
|
-
| Runtime | Python 3.
|
|
20
|
+
| Runtime | Python 3.11+ |
|
|
21
21
|
| CLI framework | Typer |
|
|
22
22
|
| Terminal rendering | Rich |
|
|
23
23
|
| Core client | `mirrorneuron-python-sdk` |
|
|
@@ -25,7 +25,7 @@ The CLI submits workflow bundles, monitors jobs, manages the local runtime servi
|
|
|
25
25
|
|
|
26
26
|
## Prerequisites
|
|
27
27
|
|
|
28
|
-
- Python 3.
|
|
28
|
+
- Python 3.11 or newer.
|
|
29
29
|
- A MirrorNeuron core reachable over gRPC.
|
|
30
30
|
- Docker for the default local core and Redis workflow.
|
|
31
31
|
- Optional: the released-package installer from `mn-deploy`, which installs and wires the CLI automatically.
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mirrorneuron-cli
|
|
3
|
-
Version: 1.1.
|
|
3
|
+
Version: 1.1.2
|
|
4
4
|
Summary: MirrorNeuron CLI
|
|
5
5
|
License-Expression: MIT
|
|
6
6
|
Classifier: Programming Language :: Python :: 3
|
|
7
|
-
Requires-Python: >=3.
|
|
7
|
+
Requires-Python: >=3.11
|
|
8
8
|
Description-Content-Type: text/markdown
|
|
9
9
|
License-File: LICENSE
|
|
10
10
|
Requires-Dist: mirrorneuron-python-sdk
|
|
@@ -31,7 +31,7 @@ The CLI submits workflow bundles, monitors jobs, manages the local runtime servi
|
|
|
31
31
|
|
|
32
32
|
| Area | Tooling |
|
|
33
33
|
| --- | --- |
|
|
34
|
-
| Runtime | Python 3.
|
|
34
|
+
| Runtime | Python 3.11+ |
|
|
35
35
|
| CLI framework | Typer |
|
|
36
36
|
| Terminal rendering | Rich |
|
|
37
37
|
| Core client | `mirrorneuron-python-sdk` |
|
|
@@ -39,7 +39,7 @@ The CLI submits workflow bundles, monitors jobs, manages the local runtime servi
|
|
|
39
39
|
|
|
40
40
|
## Prerequisites
|
|
41
41
|
|
|
42
|
-
- Python 3.
|
|
42
|
+
- Python 3.11 or newer.
|
|
43
43
|
- A MirrorNeuron core reachable over gRPC.
|
|
44
44
|
- Docker for the default local core and Redis workflow.
|
|
45
45
|
- Optional: the released-package installer from `mn-deploy`, which installs and wires the CLI automatically.
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import sys
|
|
2
1
|
import grpc
|
|
3
2
|
from rich.console import Console
|
|
4
3
|
from mn_cli.config import CliConfig
|
|
@@ -38,7 +37,7 @@ def handle_cli_error(e: Exception, console: Console, context: str = ""):
|
|
|
38
37
|
elif code == grpc.StatusCode.INTERNAL and "not found" in str(details).lower():
|
|
39
38
|
console.print(f"[red]Error: Cannot find the job by ID. ({details})[/red]")
|
|
40
39
|
elif code == grpc.StatusCode.INTERNAL and "terminal state" in str(details).lower():
|
|
41
|
-
console.print(
|
|
40
|
+
console.print("[red]Error: Job is already in a terminal state and cannot be modified.[/red]")
|
|
42
41
|
elif code == grpc.StatusCode.RESOURCE_EXHAUSTED:
|
|
43
42
|
console.print("[yellow]Runtime is under CPU/GPU/memory pressure and is not accepting new jobs.[/yellow]")
|
|
44
43
|
console.print(f"[dim]{details}[/dim]")
|
|
@@ -224,7 +224,6 @@ def _stream_and_format_events(
|
|
|
224
224
|
)
|
|
225
225
|
|
|
226
226
|
status_text = "Unknown / Detached"
|
|
227
|
-
status_color = "yellow"
|
|
228
227
|
msg_count = 0
|
|
229
228
|
|
|
230
229
|
try:
|
|
@@ -284,12 +283,10 @@ def _stream_and_format_events(
|
|
|
284
283
|
description="[green]Completed successfully.",
|
|
285
284
|
)
|
|
286
285
|
status_text = "Success"
|
|
287
|
-
status_color = "green"
|
|
288
286
|
break
|
|
289
287
|
elif event_type == "job_failed":
|
|
290
288
|
progress.update(job_task, description="[red]Job failed.")
|
|
291
289
|
status_text = "Failed"
|
|
292
|
-
status_color = "red"
|
|
293
290
|
break
|
|
294
291
|
else:
|
|
295
292
|
progress.update(
|
|
@@ -706,7 +703,7 @@ def _live_monitor(job_id: str):
|
|
|
706
703
|
view = MonitorView()
|
|
707
704
|
|
|
708
705
|
try:
|
|
709
|
-
with Live(view, refresh_per_second=12, console=console)
|
|
706
|
+
with Live(view, refresh_per_second=12, console=console):
|
|
710
707
|
while True:
|
|
711
708
|
try:
|
|
712
709
|
job_json = client.get_job(job_id)
|
|
@@ -771,7 +768,7 @@ def result(job_id: str):
|
|
|
771
768
|
if res_file.exists():
|
|
772
769
|
console.print(f"[green]Final result saved to: {res_file}[/green]")
|
|
773
770
|
else:
|
|
774
|
-
console.print(
|
|
771
|
+
console.print("[yellow]No final result found (job might not be completed).[/yellow]")
|
|
775
772
|
|
|
776
773
|
if stream_file.exists():
|
|
777
774
|
console.print(f"[green]Stream results saved to: {stream_file}[/green]")
|
|
@@ -25,7 +25,7 @@ def generate_live_layout(job_id: str, data: Dict[str, Any]) -> Group:
|
|
|
25
25
|
frames = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"]
|
|
26
26
|
idx = int(time.time() * 12.5) % len(frames)
|
|
27
27
|
spinner_str = f"[cyan]{frames[idx]}[/cyan]"
|
|
28
|
-
except:
|
|
28
|
+
except Exception:
|
|
29
29
|
pass
|
|
30
30
|
|
|
31
31
|
info_text = (
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import pytest
|
|
2
1
|
import json
|
|
3
2
|
import logging
|
|
4
3
|
import re
|
|
@@ -287,7 +286,7 @@ def test_job_log_writer_extracts_web_ui_url_once():
|
|
|
287
286
|
assert writer.record_web_ui_url(event) is None
|
|
288
287
|
|
|
289
288
|
def test_run_error_submitting(mocker, tmp_path):
|
|
290
|
-
|
|
289
|
+
mocker.patch('mn_cli.libs.run_cmds.client.submit_job', side_effect=Exception("API failure"))
|
|
291
290
|
|
|
292
291
|
bundle_dir = tmp_path / "run_bundle"
|
|
293
292
|
bundle_dir.mkdir()
|
|
@@ -300,8 +299,8 @@ def test_run_error_submitting(mocker, tmp_path):
|
|
|
300
299
|
assert "Error running bundle: API failure" in result.stdout
|
|
301
300
|
|
|
302
301
|
def test_run_keyboard_interrupt(mocker, tmp_path):
|
|
303
|
-
|
|
304
|
-
|
|
302
|
+
mocker.patch('mn_cli.libs.run_cmds.client.submit_job', return_value="job-123")
|
|
303
|
+
mocker.patch('mn_cli.libs.run_cmds.client.stream_events', side_effect=KeyboardInterrupt)
|
|
305
304
|
|
|
306
305
|
bundle_dir = tmp_path / "run_bundle"
|
|
307
306
|
bundle_dir.mkdir()
|
|
@@ -343,7 +342,7 @@ def test_monitor_error(mocker):
|
|
|
343
342
|
assert result.exit_code == 0
|
|
344
343
|
assert "Error fetching job: Network fail" in result.stdout
|
|
345
344
|
def test_result_success(mocker, tmp_path):
|
|
346
|
-
|
|
345
|
+
mocker.patch('mn_cli.libs.run_cmds.client.get_job', return_value=json.dumps({
|
|
347
346
|
"job": {"status": "completed", "result": {"test": "result"}},
|
|
348
347
|
"recent_events": []
|
|
349
348
|
}))
|
|
@@ -378,7 +377,7 @@ def test_result_error(mocker):
|
|
|
378
377
|
assert "Error fetching results: DB Error" in result.stdout
|
|
379
378
|
|
|
380
379
|
def test_stream_bad_json(mocker, tmp_path):
|
|
381
|
-
|
|
380
|
+
mocker.patch('mn_cli.libs.run_cmds.client.stream_events', return_value=[
|
|
382
381
|
"invalid json format",
|
|
383
382
|
json.dumps({"type": "job_failed"})
|
|
384
383
|
])
|
|
@@ -415,7 +414,7 @@ def test_stream_all_events(mocker, tmp_path):
|
|
|
415
414
|
json.dumps({"type": "custom_progressive", "payload": {"foo": "progressive"}}),
|
|
416
415
|
json.dumps({"type": "job_completed", "result": {"foo": "bar"}})
|
|
417
416
|
]
|
|
418
|
-
|
|
417
|
+
mocker.patch('mn_cli.libs.run_cmds.client.stream_events', return_value=events)
|
|
419
418
|
mocker.patch('mn_cli.libs.run_cmds.client.submit_job', return_value="job-123")
|
|
420
419
|
|
|
421
420
|
bundle_dir = tmp_path / "run_bundle"
|
|
@@ -430,7 +429,7 @@ def test_stream_all_events(mocker, tmp_path):
|
|
|
430
429
|
assert "result_stream.txt" in result.stdout
|
|
431
430
|
|
|
432
431
|
def test_stream_keyboard_interrupt(mocker, tmp_path):
|
|
433
|
-
|
|
432
|
+
mocker.patch('mn_cli.libs.run_cmds.client.stream_events', side_effect=KeyboardInterrupt)
|
|
434
433
|
mocker.patch('mn_cli.libs.run_cmds.client.submit_job', return_value="job-123")
|
|
435
434
|
|
|
436
435
|
bundle_dir = tmp_path / "run_bundle"
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
import pytest
|
|
2
|
-
import os
|
|
3
|
-
import signal
|
|
4
2
|
import subprocess
|
|
5
3
|
from io import StringIO
|
|
6
|
-
from pathlib import Path
|
|
7
4
|
from rich.console import Console
|
|
8
5
|
from mn_cli.server_cmds import check_status, kill_tree, _start_server, find_web_ui_dir, _start_web_ui_if_installed, _print_service_endpoints
|
|
9
6
|
import typer
|
|
@@ -34,7 +31,7 @@ def test_kill_tree(mocker):
|
|
|
34
31
|
mock_kill = mocker.patch('mn_cli.server_cmds.os.kill')
|
|
35
32
|
|
|
36
33
|
# Mock pgrep to return children
|
|
37
|
-
|
|
34
|
+
mocker.patch('mn_cli.server_cmds.subprocess.check_output', side_effect=[
|
|
38
35
|
b" 1235 \n 1236 \n", # First call for parent 1234
|
|
39
36
|
subprocess.CalledProcessError(1, "pgrep"), # Second call for child 1235
|
|
40
37
|
subprocess.CalledProcessError(1, "pgrep") # Third call for child 1236
|
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
import pytest
|
|
2
1
|
from typer.testing import CliRunner
|
|
3
2
|
from mn_cli.main import app
|
|
4
|
-
import os
|
|
5
|
-
from pathlib import Path
|
|
6
3
|
|
|
7
4
|
runner = CliRunner()
|
|
8
5
|
|
|
@@ -28,7 +25,7 @@ def test_leave_success(mocker):
|
|
|
28
25
|
|
|
29
26
|
def test_leave_error(mocker):
|
|
30
27
|
import mn_cli.shared
|
|
31
|
-
|
|
28
|
+
mocker.patch.object(mn_cli.shared.client, 'remove_node', side_effect=Exception("Timeout"))
|
|
32
29
|
result = runner.invoke(app, ["leave", "mirror_neuron@1.2.3.4"])
|
|
33
30
|
assert result.exit_code == 0
|
|
34
31
|
assert "Error removing node: Timeout" in result.stdout
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mirrorneuron_cli-1.1.1 → mirrorneuron_cli-1.1.2}/mirrorneuron_cli.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{mirrorneuron_cli-1.1.1 → mirrorneuron_cli-1.1.2}/mirrorneuron_cli.egg-info/entry_points.txt
RENAMED
|
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
|