dayhoff-tools 1.13.8__py3-none-any.whl → 1.13.10__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/engines_studios/api_client.py +3 -3
- dayhoff_tools/cli/engines_studios/progress.py +6 -2
- dayhoff_tools/cli/engines_studios/simulators/studio_list_simulator.py +61 -12
- dayhoff_tools/cli/engines_studios/studio_commands.py +68 -11
- {dayhoff_tools-1.13.8.dist-info → dayhoff_tools-1.13.10.dist-info}/METADATA +1 -1
- {dayhoff_tools-1.13.8.dist-info → dayhoff_tools-1.13.10.dist-info}/RECORD +8 -8
- {dayhoff_tools-1.13.8.dist-info → dayhoff_tools-1.13.10.dist-info}/WHEEL +0 -0
- {dayhoff_tools-1.13.8.dist-info → dayhoff_tools-1.13.10.dist-info}/entry_points.txt +0 -0
|
@@ -120,7 +120,7 @@ class StudioManagerClient:
|
|
|
120
120
|
"""
|
|
121
121
|
url = f"{self.api_url}{path}"
|
|
122
122
|
response = requests.request(method, url, **kwargs)
|
|
123
|
-
|
|
123
|
+
|
|
124
124
|
# Parse error body if request failed
|
|
125
125
|
if not response.ok:
|
|
126
126
|
try:
|
|
@@ -128,10 +128,10 @@ class StudioManagerClient:
|
|
|
128
128
|
error_message = error_body.get("error", response.text)
|
|
129
129
|
except Exception:
|
|
130
130
|
error_message = response.text or f"HTTP {response.status_code}"
|
|
131
|
-
|
|
131
|
+
|
|
132
132
|
# Raise exception with the actual error message from API
|
|
133
133
|
raise RuntimeError(error_message)
|
|
134
|
-
|
|
134
|
+
|
|
135
135
|
return response.json()
|
|
136
136
|
|
|
137
137
|
# Engine operations
|
|
@@ -207,8 +207,12 @@ def format_idle_state(
|
|
|
207
207
|
|
|
208
208
|
if isinstance(value, list):
|
|
209
209
|
if value: # Only show non-empty lists
|
|
210
|
-
#
|
|
211
|
-
if key
|
|
210
|
+
# Show workload containers with clear header
|
|
211
|
+
if key == "containers":
|
|
212
|
+
# Show actual workload container names that are keeping engine active
|
|
213
|
+
for item in value[:5]:
|
|
214
|
+
lines.append(f" • {item}")
|
|
215
|
+
elif key in ["connections", "sessions"]:
|
|
212
216
|
# Just show the items with bullets, no header
|
|
213
217
|
for item in value[:5]:
|
|
214
218
|
lines.append(f" • {item}")
|
|
@@ -20,7 +20,9 @@ def colorize(text: str, color_code: str) -> str:
|
|
|
20
20
|
return f"\033[{color_code}m{text}\033[0m"
|
|
21
21
|
|
|
22
22
|
|
|
23
|
-
def format_list_output(
|
|
23
|
+
def format_list_output(
|
|
24
|
+
studios: list[dict[str, Any]], engines_map: dict[str, str], env: str = "dev"
|
|
25
|
+
) -> None:
|
|
24
26
|
"""Format and print studio list output matching the actual CLI."""
|
|
25
27
|
|
|
26
28
|
# Header with blue account name
|
|
@@ -31,7 +33,9 @@ def format_list_output(studios: list[dict[str, Any]], engines_map: dict[str, str
|
|
|
31
33
|
return
|
|
32
34
|
|
|
33
35
|
# Calculate dynamic width for User column (longest user + 2 for padding)
|
|
34
|
-
max_user_len = max(
|
|
36
|
+
max_user_len = max(
|
|
37
|
+
(len(studio.get("user", "unknown")) for studio in studios), default=4
|
|
38
|
+
)
|
|
35
39
|
user_width = max(max_user_len + 2, len("User") + 2)
|
|
36
40
|
|
|
37
41
|
# Calculate dynamic width for Attached To column
|
|
@@ -41,7 +45,9 @@ def format_list_output(studios: list[dict[str, Any]], engines_map: dict[str, str
|
|
|
41
45
|
instance_id = studio["attached_to"]
|
|
42
46
|
engine_name = engines_map.get(instance_id, "unknown")
|
|
43
47
|
max_attached_len = max(max_attached_len, len(engine_name))
|
|
44
|
-
attached_width = max(
|
|
48
|
+
attached_width = max(
|
|
49
|
+
max_attached_len + 2, len("Attached To") + 2, 3
|
|
50
|
+
) # At least 3 for "-"
|
|
45
51
|
|
|
46
52
|
# Fixed widths for other columns
|
|
47
53
|
status_width = 12
|
|
@@ -49,13 +55,39 @@ def format_list_output(studios: list[dict[str, Any]], engines_map: dict[str, str
|
|
|
49
55
|
id_width = 25
|
|
50
56
|
|
|
51
57
|
# Table top border
|
|
52
|
-
print(
|
|
58
|
+
print(
|
|
59
|
+
"╭"
|
|
60
|
+
+ "─" * (user_width + 1)
|
|
61
|
+
+ "┬"
|
|
62
|
+
+ "─" * (status_width + 1)
|
|
63
|
+
+ "┬"
|
|
64
|
+
+ "─" * (attached_width + 1)
|
|
65
|
+
+ "┬"
|
|
66
|
+
+ "─" * (size_width + 1)
|
|
67
|
+
+ "┬"
|
|
68
|
+
+ "─" * (id_width + 1)
|
|
69
|
+
+ "╮"
|
|
70
|
+
)
|
|
53
71
|
|
|
54
72
|
# Table header
|
|
55
|
-
print(
|
|
73
|
+
print(
|
|
74
|
+
f"│ {'User':<{user_width}}│ {'Status':<{status_width}}│ {'Attached To':<{attached_width}}│ {'Size':<{size_width}}│ {'Studio ID':<{id_width}}│"
|
|
75
|
+
)
|
|
56
76
|
|
|
57
77
|
# Header separator
|
|
58
|
-
print(
|
|
78
|
+
print(
|
|
79
|
+
"├"
|
|
80
|
+
+ "─" * (user_width + 1)
|
|
81
|
+
+ "┼"
|
|
82
|
+
+ "─" * (status_width + 1)
|
|
83
|
+
+ "┼"
|
|
84
|
+
+ "─" * (attached_width + 1)
|
|
85
|
+
+ "┼"
|
|
86
|
+
+ "─" * (size_width + 1)
|
|
87
|
+
+ "┼"
|
|
88
|
+
+ "─" * (id_width + 1)
|
|
89
|
+
+ "┤"
|
|
90
|
+
)
|
|
59
91
|
|
|
60
92
|
# Table rows
|
|
61
93
|
for studio in studios:
|
|
@@ -67,7 +99,7 @@ def format_list_output(studios: list[dict[str, Any]], engines_map: dict[str, str
|
|
|
67
99
|
|
|
68
100
|
# Truncate if needed
|
|
69
101
|
if len(user) > user_width - 1:
|
|
70
|
-
user = user[:user_width - 1]
|
|
102
|
+
user = user[: user_width - 1]
|
|
71
103
|
|
|
72
104
|
# Color the user (blue)
|
|
73
105
|
user_display = colorize(f"{user:<{user_width}}", "34")
|
|
@@ -75,7 +107,9 @@ def format_list_output(studios: list[dict[str, Any]], engines_map: dict[str, str
|
|
|
75
107
|
# Format status - display "in-use" as "attached" in purple
|
|
76
108
|
if status == "in-use":
|
|
77
109
|
display_status = "attached"
|
|
78
|
-
status_display = colorize(
|
|
110
|
+
status_display = colorize(
|
|
111
|
+
f"{display_status:<{status_width}}", "35"
|
|
112
|
+
) # Purple
|
|
79
113
|
elif status == "available":
|
|
80
114
|
status_display = colorize(f"{status:<{status_width}}", "32") # Green
|
|
81
115
|
elif status in ["attaching", "detaching"]:
|
|
@@ -99,10 +133,24 @@ def format_list_output(studios: list[dict[str, Any]], engines_map: dict[str, str
|
|
|
99
133
|
# Color the studio ID (grey)
|
|
100
134
|
studio_id_display = colorize(f"{studio_id:<{id_width}}", "90")
|
|
101
135
|
|
|
102
|
-
print(
|
|
136
|
+
print(
|
|
137
|
+
f"│ {user_display}│ {status_display}│ {attached_display}│ {size:<{size_width}}│ {studio_id_display}│"
|
|
138
|
+
)
|
|
103
139
|
|
|
104
140
|
# Table bottom border
|
|
105
|
-
print(
|
|
141
|
+
print(
|
|
142
|
+
"╰"
|
|
143
|
+
+ "─" * (user_width + 1)
|
|
144
|
+
+ "┴"
|
|
145
|
+
+ "─" * (status_width + 1)
|
|
146
|
+
+ "┴"
|
|
147
|
+
+ "─" * (attached_width + 1)
|
|
148
|
+
+ "┴"
|
|
149
|
+
+ "─" * (size_width + 1)
|
|
150
|
+
+ "┴"
|
|
151
|
+
+ "─" * (id_width + 1)
|
|
152
|
+
+ "╯"
|
|
153
|
+
)
|
|
106
154
|
|
|
107
155
|
print(f"Total: {len(studios)}\n")
|
|
108
156
|
|
|
@@ -309,7 +357,9 @@ def main():
|
|
|
309
357
|
print("=" * 80 + "\n")
|
|
310
358
|
|
|
311
359
|
env = args.env if args.env else scenario_data["env"]
|
|
312
|
-
format_list_output(
|
|
360
|
+
format_list_output(
|
|
361
|
+
scenario_data["studios"], scenario_data["engines_map"], env
|
|
362
|
+
)
|
|
313
363
|
print() # Extra newline between scenarios
|
|
314
364
|
else:
|
|
315
365
|
# Show specific scenario
|
|
@@ -322,4 +372,3 @@ def main():
|
|
|
322
372
|
|
|
323
373
|
if __name__ == "__main__":
|
|
324
374
|
main()
|
|
325
|
-
|
|
@@ -222,9 +222,20 @@ def studio_status(user: Optional[str], env: Optional[str]):
|
|
|
222
222
|
click.echo(f"User: {studio['user']}")
|
|
223
223
|
# Status in blue
|
|
224
224
|
click.echo(f"Status: \033[34m{studio['status']}\033[0m")
|
|
225
|
-
# Attached to in blue (if present)
|
|
225
|
+
# Attached to in blue (if present) - resolve instance ID to engine name
|
|
226
226
|
if studio.get("attached_to"):
|
|
227
|
-
|
|
227
|
+
instance_id = studio["attached_to"]
|
|
228
|
+
# Try to resolve instance ID to engine name by searching engines list
|
|
229
|
+
engine_name = instance_id # Default to instance ID if not found
|
|
230
|
+
try:
|
|
231
|
+
engines_result = client.list_engines()
|
|
232
|
+
for engine in engines_result.get("engines", []):
|
|
233
|
+
if engine.get("instance_id") == instance_id:
|
|
234
|
+
engine_name = engine.get("name", instance_id)
|
|
235
|
+
break
|
|
236
|
+
except Exception:
|
|
237
|
+
pass # Fall back to instance ID
|
|
238
|
+
click.echo(f"Attached to: \033[34m{engine_name}\033[0m")
|
|
228
239
|
click.echo(f"Account: {env}")
|
|
229
240
|
click.echo(f"Size: {studio['size_gb']}GB")
|
|
230
241
|
if studio.get("created_at"):
|
|
@@ -272,7 +283,9 @@ def list_studios(env: Optional[str]):
|
|
|
272
283
|
engines_map[engine["instance_id"]] = engine["name"]
|
|
273
284
|
|
|
274
285
|
# Calculate dynamic width for User column (longest user + 2 for padding)
|
|
275
|
-
max_user_len = max(
|
|
286
|
+
max_user_len = max(
|
|
287
|
+
(len(studio.get("user", "unknown")) for studio in studios), default=4
|
|
288
|
+
)
|
|
276
289
|
user_width = max(max_user_len + 2, len("User") + 2)
|
|
277
290
|
|
|
278
291
|
# Calculate dynamic width for Attached To column
|
|
@@ -282,7 +295,9 @@ def list_studios(env: Optional[str]):
|
|
|
282
295
|
instance_id = studio["attached_to"]
|
|
283
296
|
engine_name = engines_map.get(instance_id, "unknown")
|
|
284
297
|
max_attached_len = max(max_attached_len, len(engine_name))
|
|
285
|
-
attached_width = max(
|
|
298
|
+
attached_width = max(
|
|
299
|
+
max_attached_len + 2, len("Attached To") + 2, 3
|
|
300
|
+
) # At least 3 for "-"
|
|
286
301
|
|
|
287
302
|
# Fixed widths for other columns - reordered to [User, Status, Attached To, Size, Studio ID]
|
|
288
303
|
status_width = 12
|
|
@@ -290,7 +305,19 @@ def list_studios(env: Optional[str]):
|
|
|
290
305
|
id_width = 25
|
|
291
306
|
|
|
292
307
|
# Table top border
|
|
293
|
-
click.echo(
|
|
308
|
+
click.echo(
|
|
309
|
+
"╭"
|
|
310
|
+
+ "─" * (user_width + 1)
|
|
311
|
+
+ "┬"
|
|
312
|
+
+ "─" * (status_width + 1)
|
|
313
|
+
+ "┬"
|
|
314
|
+
+ "─" * (attached_width + 1)
|
|
315
|
+
+ "┬"
|
|
316
|
+
+ "─" * (size_width + 1)
|
|
317
|
+
+ "┬"
|
|
318
|
+
+ "─" * (id_width + 1)
|
|
319
|
+
+ "╮"
|
|
320
|
+
)
|
|
294
321
|
|
|
295
322
|
# Table header - reordered to [User, Status, Attached To, Size, Studio ID]
|
|
296
323
|
click.echo(
|
|
@@ -298,7 +325,19 @@ def list_studios(env: Optional[str]):
|
|
|
298
325
|
)
|
|
299
326
|
|
|
300
327
|
# Header separator
|
|
301
|
-
click.echo(
|
|
328
|
+
click.echo(
|
|
329
|
+
"├"
|
|
330
|
+
+ "─" * (user_width + 1)
|
|
331
|
+
+ "┼"
|
|
332
|
+
+ "─" * (status_width + 1)
|
|
333
|
+
+ "┼"
|
|
334
|
+
+ "─" * (attached_width + 1)
|
|
335
|
+
+ "┼"
|
|
336
|
+
+ "─" * (size_width + 1)
|
|
337
|
+
+ "┼"
|
|
338
|
+
+ "─" * (id_width + 1)
|
|
339
|
+
+ "┤"
|
|
340
|
+
)
|
|
302
341
|
|
|
303
342
|
# Table rows
|
|
304
343
|
for studio in studios:
|
|
@@ -310,7 +349,7 @@ def list_studios(env: Optional[str]):
|
|
|
310
349
|
|
|
311
350
|
# Truncate if needed
|
|
312
351
|
if len(user) > user_width - 1:
|
|
313
|
-
user = user[:user_width - 1]
|
|
352
|
+
user = user[: user_width - 1]
|
|
314
353
|
|
|
315
354
|
# Color the user (blue)
|
|
316
355
|
user_display = f"\033[34m{user:<{user_width}}\033[0m"
|
|
@@ -318,7 +357,9 @@ def list_studios(env: Optional[str]):
|
|
|
318
357
|
# Format status - display "in-use" as "attached" in purple
|
|
319
358
|
if status == "in-use":
|
|
320
359
|
display_status = "attached"
|
|
321
|
-
status_display =
|
|
360
|
+
status_display = (
|
|
361
|
+
f"\033[35m{display_status:<{status_width}}\033[0m" # Purple
|
|
362
|
+
)
|
|
322
363
|
elif status == "available":
|
|
323
364
|
status_display = f"\033[32m{status:<{status_width}}\033[0m" # Green
|
|
324
365
|
elif status in ["attaching", "detaching"]:
|
|
@@ -326,9 +367,13 @@ def list_studios(env: Optional[str]):
|
|
|
326
367
|
elif status == "attached":
|
|
327
368
|
status_display = f"\033[35m{status:<{status_width}}\033[0m" # Purple
|
|
328
369
|
elif status == "error":
|
|
329
|
-
status_display =
|
|
370
|
+
status_display = (
|
|
371
|
+
f"\033[31m{status:<{status_width}}\033[0m" # Red for error
|
|
372
|
+
)
|
|
330
373
|
else:
|
|
331
|
-
status_display =
|
|
374
|
+
status_display = (
|
|
375
|
+
f"{status:<{status_width}}" # No color for other states
|
|
376
|
+
)
|
|
332
377
|
|
|
333
378
|
# Format Attached To column
|
|
334
379
|
if attached_to:
|
|
@@ -347,7 +392,19 @@ def list_studios(env: Optional[str]):
|
|
|
347
392
|
)
|
|
348
393
|
|
|
349
394
|
# Table bottom border
|
|
350
|
-
click.echo(
|
|
395
|
+
click.echo(
|
|
396
|
+
"╰"
|
|
397
|
+
+ "─" * (user_width + 1)
|
|
398
|
+
+ "┴"
|
|
399
|
+
+ "─" * (status_width + 1)
|
|
400
|
+
+ "┴"
|
|
401
|
+
+ "─" * (attached_width + 1)
|
|
402
|
+
+ "┴"
|
|
403
|
+
+ "─" * (size_width + 1)
|
|
404
|
+
+ "┴"
|
|
405
|
+
+ "─" * (id_width + 1)
|
|
406
|
+
+ "╯"
|
|
407
|
+
)
|
|
351
408
|
|
|
352
409
|
click.echo(f"Total: {len(studios)}\n")
|
|
353
410
|
|
|
@@ -11,20 +11,20 @@ dayhoff_tools/cli/engine1/engine_management.py,sha256=s_H3FtMlKsdfzR8pwV-j2W2QX-
|
|
|
11
11
|
dayhoff_tools/cli/engine1/shared.py,sha256=Ecx6I1jtzmxQDn3BezKpgpQ4SJeZf4SZjUCLg-67p80,16844
|
|
12
12
|
dayhoff_tools/cli/engine1/studio_commands.py,sha256=VwTQujz32-uMcYusDRE73SdzRpgvIkv7ZAF4zRv6AzA,30266
|
|
13
13
|
dayhoff_tools/cli/engines_studios/__init__.py,sha256=E6aG0C6qjJnJuClemSKRFlYvLUL49MQZOvfqNQ7SDKs,159
|
|
14
|
-
dayhoff_tools/cli/engines_studios/api_client.py,sha256=
|
|
14
|
+
dayhoff_tools/cli/engines_studios/api_client.py,sha256=7puTEpr3ukcguZr5aqRaSXLKM9Et799lnXwiywPvPz8,13459
|
|
15
15
|
dayhoff_tools/cli/engines_studios/auth.py,sha256=rwetV5hp4jSvK8FyvKgXCnezLOZx1aW8oiSDc6U83iE,5189
|
|
16
16
|
dayhoff_tools/cli/engines_studios/engine-studio-cli.md,sha256=or4k7ZZKPMTkvu67PdcUTE2_cxjnj0HQxxTuJZR1uiA,29924
|
|
17
17
|
dayhoff_tools/cli/engines_studios/engine_commands.py,sha256=8utssuiLfxrff3Pk3PjMSUIVMU83mm9N8-Ny1uQr9es,38371
|
|
18
|
-
dayhoff_tools/cli/engines_studios/progress.py,sha256=
|
|
18
|
+
dayhoff_tools/cli/engines_studios/progress.py,sha256=VW70t7sEHlbLpCi6LOaY19Rp1Kx6Rt9CKNnmaZWFteA,9496
|
|
19
19
|
dayhoff_tools/cli/engines_studios/simulators/cli-simulators.md,sha256=FZJl6nehdr2Duht2cx3yijcak0yKyOaHTrTzvFTAfZs,4976
|
|
20
20
|
dayhoff_tools/cli/engines_studios/simulators/demo.sh,sha256=8tYABSCxLNXqGs-4r071V9mpKNZ5DTQ34WZ-v3d5s94,5364
|
|
21
21
|
dayhoff_tools/cli/engines_studios/simulators/engine_list_simulator.py,sha256=vUrB6gV9UX74L5uCRMTVcPmk_1ZOuP1jYJf6cMP7dOE,9525
|
|
22
22
|
dayhoff_tools/cli/engines_studios/simulators/engine_status_simulator.py,sha256=KUm3gA2MiRgGrQV7KURhb5zabM18-30z_ugRjiq5iso,13024
|
|
23
23
|
dayhoff_tools/cli/engines_studios/simulators/idle_status_simulator.py,sha256=F_MfEXdPKNVDCKgJV72QyU2oMG8hLt-Bwic4yFadRXE,17570
|
|
24
24
|
dayhoff_tools/cli/engines_studios/simulators/simulator_utils.py,sha256=HA08pIMJWV3OFrWj3Ca8GldvgJZfFoTOloyLK0UWMgA,6729
|
|
25
|
-
dayhoff_tools/cli/engines_studios/simulators/studio_list_simulator.py,sha256=
|
|
25
|
+
dayhoff_tools/cli/engines_studios/simulators/studio_list_simulator.py,sha256=ntizeR0BJLdJOwCRBKPajc2xT-BL7SNnONxfgxXDgr8,11609
|
|
26
26
|
dayhoff_tools/cli/engines_studios/simulators/studio_status_simulator.py,sha256=6WvpnRawJVaQf_H81zuR1_66igRRVxPxjAt8e69xjp4,5394
|
|
27
|
-
dayhoff_tools/cli/engines_studios/studio_commands.py,sha256=
|
|
27
|
+
dayhoff_tools/cli/engines_studios/studio_commands.py,sha256=4ul6i8HDHZTffavu1y_j4kwvsDNvjMvYMWbZGXN8nKY,25597
|
|
28
28
|
dayhoff_tools/cli/main.py,sha256=Nz_jtbppmvWKHZydQ0nkt_eejccJE90ces8xCGrerdY,7086
|
|
29
29
|
dayhoff_tools/cli/swarm_commands.py,sha256=5EyKj8yietvT5lfoz8Zx0iQvVaNgc3SJX1z2zQR6o6M,5614
|
|
30
30
|
dayhoff_tools/cli/utility_commands.py,sha256=e2P4dCCtoqMUGNyb0lFBZ6GZpl5Zslm1qqE5qIvsy38,50765
|
|
@@ -48,7 +48,7 @@ dayhoff_tools/intake/uniprot.py,sha256=BZYJQF63OtPcBBnQ7_P9gulxzJtqyorgyuDiPeOJq
|
|
|
48
48
|
dayhoff_tools/logs.py,sha256=DKdeP0k0kliRcilwvX0mUB2eipO5BdWUeHwh-VnsICs,838
|
|
49
49
|
dayhoff_tools/sqlite.py,sha256=jV55ikF8VpTfeQqqlHSbY8OgfyfHj8zgHNpZjBLos_E,18672
|
|
50
50
|
dayhoff_tools/warehouse.py,sha256=UETBtZD3r7WgvURqfGbyHlT7cxoiVq8isjzMuerKw8I,24475
|
|
51
|
-
dayhoff_tools-1.13.
|
|
52
|
-
dayhoff_tools-1.13.
|
|
53
|
-
dayhoff_tools-1.13.
|
|
54
|
-
dayhoff_tools-1.13.
|
|
51
|
+
dayhoff_tools-1.13.10.dist-info/METADATA,sha256=RwVcLNZbrSHXOK8jbzm9c3bPchOE3sZAET6k1VYV0zQ,2981
|
|
52
|
+
dayhoff_tools-1.13.10.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
|
|
53
|
+
dayhoff_tools-1.13.10.dist-info/entry_points.txt,sha256=iAf4jteNqW3cJm6CO6czLxjW3vxYKsyGLZ8WGmxamSc,49
|
|
54
|
+
dayhoff_tools-1.13.10.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|