dayhoff-tools 1.9.7__py3-none-any.whl → 1.9.9__py3-none-any.whl
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.
- dayhoff_tools/cli/engine_commands.py +64 -60
- {dayhoff_tools-1.9.7.dist-info → dayhoff_tools-1.9.9.dist-info}/METADATA +1 -1
- {dayhoff_tools-1.9.7.dist-info → dayhoff_tools-1.9.9.dist-info}/RECORD +5 -5
- {dayhoff_tools-1.9.7.dist-info → dayhoff_tools-1.9.9.dist-info}/WHEEL +0 -0
- {dayhoff_tools-1.9.7.dist-info → dayhoff_tools-1.9.9.dist-info}/entry_points.txt +0 -0
@@ -709,11 +709,7 @@ def engine_status(
|
|
709
709
|
engine = resolve_engine(name_or_id, engines)
|
710
710
|
|
711
711
|
# Fast status display (default)
|
712
|
-
if not detailed:
|
713
|
-
# Skip the API call for studios - use basic info we already have
|
714
|
-
attached_studios = []
|
715
|
-
studio_user = engine.get("user") # Use the engine's user as studio owner
|
716
|
-
|
712
|
+
if not detailed:
|
717
713
|
# Fetch idle status via SSM with longer timeout
|
718
714
|
ssm = boto3.client("ssm", region_name="us-east-1")
|
719
715
|
idle_data = None # Use None to indicate no data received
|
@@ -781,7 +777,11 @@ def engine_status(
|
|
781
777
|
if is_idle:
|
782
778
|
if isinstance(timeout_sec, int) and isinstance(idle_seconds, int):
|
783
779
|
remaining = max(0, timeout_sec - idle_seconds)
|
784
|
-
|
780
|
+
remaining_mins = remaining // 60
|
781
|
+
if remaining_mins == 0:
|
782
|
+
idle_disp = f" [yellow]Idle {idle_seconds//60}m/{timeout_sec//60}m: [red]<1m[/red] left[/yellow]"
|
783
|
+
else:
|
784
|
+
idle_disp = f" [yellow]Idle {idle_seconds//60}m/{timeout_sec//60}m: [red]{remaining_mins}m[/red] left[/yellow]"
|
785
785
|
else:
|
786
786
|
idle_disp = " [yellow]Idle ?/?[/yellow]"
|
787
787
|
else:
|
@@ -790,17 +790,12 @@ def engine_status(
|
|
790
790
|
|
791
791
|
# Build status lines - minimal info for fast view
|
792
792
|
status_lines = [
|
793
|
-
f"[blue]{engine['name']}[/blue] {run_disp}{idle_disp}
|
793
|
+
f"[blue]{engine['name']}[/blue] {run_disp}{idle_disp}",
|
794
794
|
]
|
795
795
|
|
796
|
-
# Add studio owner if known
|
797
|
-
if studio_user:
|
798
|
-
status_lines.append(f"Studio: [magenta]{studio_user}[/magenta]")
|
799
|
-
|
800
796
|
# Add activity sensors if we have idle data
|
801
797
|
if idle_data and idle_data.get("reasons"):
|
802
|
-
status_lines.append("")
|
803
|
-
status_lines.append("[bold]Activity:[/bold]")
|
798
|
+
status_lines.append("") # blank line before sensors
|
804
799
|
|
805
800
|
sensor_map = {
|
806
801
|
"CoffeeLockSensor": ("☕", "Coffee"),
|
@@ -889,14 +884,14 @@ def engine_status(
|
|
889
884
|
|
890
885
|
# Compose Active/Idle header with extra detail when idle
|
891
886
|
def _compute_active_disp(idle_info: Dict[str, Any]) -> str:
|
887
|
+
# If we don't have idle info or it's explicitly unavailable, show N/A
|
888
|
+
if not idle_info or idle_info.get("available") == False:
|
889
|
+
return "[dim]N/A[/dim]"
|
890
|
+
|
892
891
|
if idle_info.get("status") == "active":
|
893
892
|
return "[green]Active[/green]"
|
894
893
|
if running_state in ("stopped", "stopping"):
|
895
894
|
return "[dim]N/A[/dim]"
|
896
|
-
|
897
|
-
# If we don't have idle info at all, show N/A
|
898
|
-
if not idle_info.get("available"):
|
899
|
-
return "[dim]N/A[/dim]"
|
900
895
|
|
901
896
|
# If idle, show time/threshold with time remaining if available
|
902
897
|
if idle_info.get("status") == "idle":
|
@@ -904,7 +899,11 @@ def engine_status(
|
|
904
899
|
thresh_v = idle_info.get("idle_threshold")
|
905
900
|
if isinstance(idle_seconds_v, (int, float)) and isinstance(thresh_v, (int, float)):
|
906
901
|
remaining = max(0, int(thresh_v) - int(idle_seconds_v))
|
907
|
-
|
902
|
+
remaining_mins = remaining // 60
|
903
|
+
if remaining_mins == 0:
|
904
|
+
return f"[yellow]Idle {int(idle_seconds_v)//60}m/{int(thresh_v)//60}m: [red]<1m[/red] left[/yellow]"
|
905
|
+
else:
|
906
|
+
return f"[yellow]Idle {int(idle_seconds_v)//60}m/{int(thresh_v)//60}m: [red]{remaining_mins}m[/red] left[/yellow]"
|
908
907
|
elif isinstance(thresh_v, (int, float)):
|
909
908
|
return f"[yellow]Idle ?/{int(thresh_v)//60}m[/yellow]"
|
910
909
|
else:
|
@@ -949,47 +948,51 @@ def engine_status(
|
|
949
948
|
disk_usage = get_disk_usage_via_ssm(engine["instance_id"]) or "-"
|
950
949
|
status_lines.append(f"Disk: {disk_usage}")
|
951
950
|
|
952
|
-
# Idle timeout (show even when not idle)
|
953
|
-
|
954
|
-
|
955
|
-
|
956
|
-
if isinstance(idle_detector.get("idle_threshold"), (int, float)):
|
957
|
-
idle_threshold_secs = int(idle_detector["idle_threshold"])
|
958
|
-
except Exception:
|
959
|
-
idle_threshold_secs = None
|
960
|
-
|
961
|
-
if idle_threshold_secs is None and engine["state"].lower() == "running":
|
962
|
-
# Fallback: read /etc/engine.env via SSM
|
951
|
+
# Idle timeout (show even when not idle) - but only if we have data
|
952
|
+
if idle_detector.get("available"):
|
953
|
+
idle_threshold_secs: Optional[int] = None
|
954
|
+
# Prefer value from idle detector overlay if present
|
963
955
|
try:
|
964
|
-
|
965
|
-
|
966
|
-
InstanceIds=[engine["instance_id"]],
|
967
|
-
DocumentName="AWS-RunShellScript",
|
968
|
-
Parameters={
|
969
|
-
"commands": [
|
970
|
-
"grep -E '^IDLE_TIMEOUT_SECONDS=' /etc/engine.env | cut -d'=' -f2 || echo 1800",
|
971
|
-
],
|
972
|
-
"executionTimeout": ["5"],
|
973
|
-
},
|
974
|
-
)
|
975
|
-
cid = resp["Command"]["CommandId"]
|
976
|
-
time.sleep(1)
|
977
|
-
inv = ssm.get_command_invocation(
|
978
|
-
CommandId=cid, InstanceId=engine["instance_id"]
|
979
|
-
)
|
980
|
-
if inv.get("Status") == "Success":
|
981
|
-
out = (inv.get("StandardOutputContent") or "").strip()
|
982
|
-
if out:
|
983
|
-
idle_threshold_secs = int(out.splitlines()[0].strip())
|
956
|
+
if isinstance(idle_detector.get("idle_threshold"), (int, float)):
|
957
|
+
idle_threshold_secs = int(idle_detector["idle_threshold"])
|
984
958
|
except Exception:
|
985
959
|
idle_threshold_secs = None
|
986
960
|
|
987
|
-
|
988
|
-
|
961
|
+
if idle_threshold_secs is None and engine["state"].lower() == "running":
|
962
|
+
# Fallback: read /etc/engine.env via SSM
|
963
|
+
try:
|
964
|
+
ssm = boto3.client("ssm", region_name="us-east-1")
|
965
|
+
resp = ssm.send_command(
|
966
|
+
InstanceIds=[engine["instance_id"]],
|
967
|
+
DocumentName="AWS-RunShellScript",
|
968
|
+
Parameters={
|
969
|
+
"commands": [
|
970
|
+
"grep -E '^IDLE_TIMEOUT_SECONDS=' /etc/engine.env | cut -d'=' -f2 || echo '?'",
|
971
|
+
],
|
972
|
+
"executionTimeout": ["5"],
|
973
|
+
},
|
974
|
+
)
|
975
|
+
cid = resp["Command"]["CommandId"]
|
976
|
+
time.sleep(1)
|
977
|
+
inv = ssm.get_command_invocation(
|
978
|
+
CommandId=cid, InstanceId=engine["instance_id"]
|
979
|
+
)
|
980
|
+
if inv.get("Status") == "Success":
|
981
|
+
out = (inv.get("StandardOutputContent") or "").strip()
|
982
|
+
if out and out != "?" and out.isdigit():
|
983
|
+
idle_threshold_secs = int(out)
|
984
|
+
except Exception:
|
985
|
+
idle_threshold_secs = None
|
989
986
|
|
990
|
-
|
991
|
-
|
992
|
-
|
987
|
+
if idle_threshold_secs is not None:
|
988
|
+
status_lines.append(
|
989
|
+
f"Idle timeout: {idle_threshold_secs//60}m ({idle_threshold_secs}s)"
|
990
|
+
)
|
991
|
+
else:
|
992
|
+
status_lines.append("Idle timeout: unknown")
|
993
|
+
else:
|
994
|
+
# No idle detector data available
|
995
|
+
status_lines.append("Idle timeout: N/A")
|
993
996
|
|
994
997
|
# Health report (only if bootstrap finished)
|
995
998
|
if stage_val == "finished":
|
@@ -1133,13 +1136,14 @@ def engine_status(
|
|
1133
1136
|
else:
|
1134
1137
|
for k, v in overlay.items():
|
1135
1138
|
idle_detector.setdefault(k, v)
|
1139
|
+
else:
|
1140
|
+
# SSM failed - mark as unavailable if we don't have good data
|
1141
|
+
if not idle_detector.get("available"):
|
1142
|
+
idle_detector = {"available": False} # Mark as unavailable
|
1136
1143
|
|
1137
|
-
|
1138
|
-
|
1139
|
-
|
1140
|
-
top_lines[0] = f"[blue]{engine['name']}[/blue] {run_disp} {active_disp}\n"
|
1141
|
-
except Exception:
|
1142
|
-
pass
|
1144
|
+
# Recompute header display with latest data
|
1145
|
+
active_disp = _compute_active_disp(idle_detector)
|
1146
|
+
top_lines[0] = f"[blue]{engine['name']}[/blue] {run_disp} {active_disp}\n"
|
1143
1147
|
|
1144
1148
|
# Activity Sensors (show all with YES/no)
|
1145
1149
|
if idle_detector.get("available"):
|
@@ -3,7 +3,7 @@ dayhoff_tools/chemistry/standardizer.py,sha256=uMn7VwHnx02nc404eO6fRuS4rsl4dvSPf
|
|
3
3
|
dayhoff_tools/chemistry/utils.py,sha256=jt-7JgF-GeeVC421acX-bobKbLU_X94KNOW24p_P-_M,2257
|
4
4
|
dayhoff_tools/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
5
5
|
dayhoff_tools/cli/cloud_commands.py,sha256=33qcWLmq-FwEXMdL3F0OHm-5Stlh2r65CldyEZgQ1no,40904
|
6
|
-
dayhoff_tools/cli/engine_commands.py,sha256=
|
6
|
+
dayhoff_tools/cli/engine_commands.py,sha256=OHaaF28Dh1WSh2c-YKTRfIlYNCrlld0LvgyRIP9e_Hc,113202
|
7
7
|
dayhoff_tools/cli/main.py,sha256=LoFs3SI4fdCjP4pdxEAhri-_q0dmNYupmBCRE4KbBac,5933
|
8
8
|
dayhoff_tools/cli/swarm_commands.py,sha256=5EyKj8yietvT5lfoz8Zx0iQvVaNgc3SJX1z2zQR6o6M,5614
|
9
9
|
dayhoff_tools/cli/utility_commands.py,sha256=WQTHOh1MttuxaJjl2c6zMa4x7_JuaKMQgcyotYrU3GA,25883
|
@@ -27,7 +27,7 @@ dayhoff_tools/intake/uniprot.py,sha256=BZYJQF63OtPcBBnQ7_P9gulxzJtqyorgyuDiPeOJq
|
|
27
27
|
dayhoff_tools/logs.py,sha256=DKdeP0k0kliRcilwvX0mUB2eipO5BdWUeHwh-VnsICs,838
|
28
28
|
dayhoff_tools/sqlite.py,sha256=jV55ikF8VpTfeQqqlHSbY8OgfyfHj8zgHNpZjBLos_E,18672
|
29
29
|
dayhoff_tools/warehouse.py,sha256=UETBtZD3r7WgvURqfGbyHlT7cxoiVq8isjzMuerKw8I,24475
|
30
|
-
dayhoff_tools-1.9.
|
31
|
-
dayhoff_tools-1.9.
|
32
|
-
dayhoff_tools-1.9.
|
33
|
-
dayhoff_tools-1.9.
|
30
|
+
dayhoff_tools-1.9.9.dist-info/METADATA,sha256=01FYQCJJf9a5Y0BngfeSTZesnMURFjXTFPgHK30CWdA,2914
|
31
|
+
dayhoff_tools-1.9.9.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
32
|
+
dayhoff_tools-1.9.9.dist-info/entry_points.txt,sha256=iAf4jteNqW3cJm6CO6czLxjW3vxYKsyGLZ8WGmxamSc,49
|
33
|
+
dayhoff_tools-1.9.9.dist-info/RECORD,,
|
File without changes
|
File without changes
|