dayhoff-tools 1.13.8__tar.gz → 1.13.10__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.
Files changed (53) hide show
  1. {dayhoff_tools-1.13.8 → dayhoff_tools-1.13.10}/PKG-INFO +1 -1
  2. {dayhoff_tools-1.13.8 → dayhoff_tools-1.13.10}/dayhoff_tools/cli/engines_studios/api_client.py +3 -3
  3. {dayhoff_tools-1.13.8 → dayhoff_tools-1.13.10}/dayhoff_tools/cli/engines_studios/progress.py +6 -2
  4. {dayhoff_tools-1.13.8 → dayhoff_tools-1.13.10}/dayhoff_tools/cli/engines_studios/simulators/studio_list_simulator.py +61 -12
  5. {dayhoff_tools-1.13.8 → dayhoff_tools-1.13.10}/dayhoff_tools/cli/engines_studios/studio_commands.py +68 -11
  6. {dayhoff_tools-1.13.8 → dayhoff_tools-1.13.10}/pyproject.toml +1 -1
  7. {dayhoff_tools-1.13.8 → dayhoff_tools-1.13.10}/README.md +0 -0
  8. {dayhoff_tools-1.13.8 → dayhoff_tools-1.13.10}/dayhoff_tools/__init__.py +0 -0
  9. {dayhoff_tools-1.13.8 → dayhoff_tools-1.13.10}/dayhoff_tools/chemistry/standardizer.py +0 -0
  10. {dayhoff_tools-1.13.8 → dayhoff_tools-1.13.10}/dayhoff_tools/chemistry/utils.py +0 -0
  11. {dayhoff_tools-1.13.8 → dayhoff_tools-1.13.10}/dayhoff_tools/cli/__init__.py +0 -0
  12. {dayhoff_tools-1.13.8 → dayhoff_tools-1.13.10}/dayhoff_tools/cli/cloud_commands.py +0 -0
  13. {dayhoff_tools-1.13.8 → dayhoff_tools-1.13.10}/dayhoff_tools/cli/engine1/__init__.py +0 -0
  14. {dayhoff_tools-1.13.8 → dayhoff_tools-1.13.10}/dayhoff_tools/cli/engine1/engine_core.py +0 -0
  15. {dayhoff_tools-1.13.8 → dayhoff_tools-1.13.10}/dayhoff_tools/cli/engine1/engine_lifecycle.py +0 -0
  16. {dayhoff_tools-1.13.8 → dayhoff_tools-1.13.10}/dayhoff_tools/cli/engine1/engine_maintenance.py +0 -0
  17. {dayhoff_tools-1.13.8 → dayhoff_tools-1.13.10}/dayhoff_tools/cli/engine1/engine_management.py +0 -0
  18. {dayhoff_tools-1.13.8 → dayhoff_tools-1.13.10}/dayhoff_tools/cli/engine1/shared.py +0 -0
  19. {dayhoff_tools-1.13.8 → dayhoff_tools-1.13.10}/dayhoff_tools/cli/engine1/studio_commands.py +0 -0
  20. {dayhoff_tools-1.13.8 → dayhoff_tools-1.13.10}/dayhoff_tools/cli/engines_studios/__init__.py +0 -0
  21. {dayhoff_tools-1.13.8 → dayhoff_tools-1.13.10}/dayhoff_tools/cli/engines_studios/auth.py +0 -0
  22. {dayhoff_tools-1.13.8 → dayhoff_tools-1.13.10}/dayhoff_tools/cli/engines_studios/engine-studio-cli.md +0 -0
  23. {dayhoff_tools-1.13.8 → dayhoff_tools-1.13.10}/dayhoff_tools/cli/engines_studios/engine_commands.py +0 -0
  24. {dayhoff_tools-1.13.8 → dayhoff_tools-1.13.10}/dayhoff_tools/cli/engines_studios/simulators/cli-simulators.md +0 -0
  25. {dayhoff_tools-1.13.8 → dayhoff_tools-1.13.10}/dayhoff_tools/cli/engines_studios/simulators/demo.sh +0 -0
  26. {dayhoff_tools-1.13.8 → dayhoff_tools-1.13.10}/dayhoff_tools/cli/engines_studios/simulators/engine_list_simulator.py +0 -0
  27. {dayhoff_tools-1.13.8 → dayhoff_tools-1.13.10}/dayhoff_tools/cli/engines_studios/simulators/engine_status_simulator.py +0 -0
  28. {dayhoff_tools-1.13.8 → dayhoff_tools-1.13.10}/dayhoff_tools/cli/engines_studios/simulators/idle_status_simulator.py +0 -0
  29. {dayhoff_tools-1.13.8 → dayhoff_tools-1.13.10}/dayhoff_tools/cli/engines_studios/simulators/simulator_utils.py +0 -0
  30. {dayhoff_tools-1.13.8 → dayhoff_tools-1.13.10}/dayhoff_tools/cli/engines_studios/simulators/studio_status_simulator.py +0 -0
  31. {dayhoff_tools-1.13.8 → dayhoff_tools-1.13.10}/dayhoff_tools/cli/main.py +0 -0
  32. {dayhoff_tools-1.13.8 → dayhoff_tools-1.13.10}/dayhoff_tools/cli/swarm_commands.py +0 -0
  33. {dayhoff_tools-1.13.8 → dayhoff_tools-1.13.10}/dayhoff_tools/cli/utility_commands.py +0 -0
  34. {dayhoff_tools-1.13.8 → dayhoff_tools-1.13.10}/dayhoff_tools/deployment/base.py +0 -0
  35. {dayhoff_tools-1.13.8 → dayhoff_tools-1.13.10}/dayhoff_tools/deployment/deploy_aws.py +0 -0
  36. {dayhoff_tools-1.13.8 → dayhoff_tools-1.13.10}/dayhoff_tools/deployment/deploy_gcp.py +0 -0
  37. {dayhoff_tools-1.13.8 → dayhoff_tools-1.13.10}/dayhoff_tools/deployment/deploy_utils.py +0 -0
  38. {dayhoff_tools-1.13.8 → dayhoff_tools-1.13.10}/dayhoff_tools/deployment/job_runner.py +0 -0
  39. {dayhoff_tools-1.13.8 → dayhoff_tools-1.13.10}/dayhoff_tools/deployment/processors.py +0 -0
  40. {dayhoff_tools-1.13.8 → dayhoff_tools-1.13.10}/dayhoff_tools/deployment/swarm.py +0 -0
  41. {dayhoff_tools-1.13.8 → dayhoff_tools-1.13.10}/dayhoff_tools/embedders.py +0 -0
  42. {dayhoff_tools-1.13.8 → dayhoff_tools-1.13.10}/dayhoff_tools/fasta.py +0 -0
  43. {dayhoff_tools-1.13.8 → dayhoff_tools-1.13.10}/dayhoff_tools/file_ops.py +0 -0
  44. {dayhoff_tools-1.13.8 → dayhoff_tools-1.13.10}/dayhoff_tools/h5.py +0 -0
  45. {dayhoff_tools-1.13.8 → dayhoff_tools-1.13.10}/dayhoff_tools/intake/gcp.py +0 -0
  46. {dayhoff_tools-1.13.8 → dayhoff_tools-1.13.10}/dayhoff_tools/intake/gtdb.py +0 -0
  47. {dayhoff_tools-1.13.8 → dayhoff_tools-1.13.10}/dayhoff_tools/intake/kegg.py +0 -0
  48. {dayhoff_tools-1.13.8 → dayhoff_tools-1.13.10}/dayhoff_tools/intake/mmseqs.py +0 -0
  49. {dayhoff_tools-1.13.8 → dayhoff_tools-1.13.10}/dayhoff_tools/intake/structure.py +0 -0
  50. {dayhoff_tools-1.13.8 → dayhoff_tools-1.13.10}/dayhoff_tools/intake/uniprot.py +0 -0
  51. {dayhoff_tools-1.13.8 → dayhoff_tools-1.13.10}/dayhoff_tools/logs.py +0 -0
  52. {dayhoff_tools-1.13.8 → dayhoff_tools-1.13.10}/dayhoff_tools/sqlite.py +0 -0
  53. {dayhoff_tools-1.13.8 → dayhoff_tools-1.13.10}/dayhoff_tools/warehouse.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dayhoff-tools
3
- Version: 1.13.8
3
+ Version: 1.13.10
4
4
  Summary: Common tools for all the repos at Dayhoff Labs
5
5
  Author: Daniel Martin-Alarcon
6
6
  Author-email: dma@dayhofflabs.com
@@ -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
- # All lists shown with bullets, no header for containers/connections/sessions
211
- if key in ["containers", "connections", "sessions"]:
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(studios: list[dict[str, Any]], engines_map: dict[str, str], env: str = "dev") -> None:
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((len(studio.get("user", "unknown")) for studio in studios), default=4)
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(max_attached_len + 2, len("Attached To") + 2, 3) # At least 3 for "-"
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("╭" + "─" * (user_width + 1) + "┬" + "─" * (status_width + 1) + "┬" + "─" * (attached_width + 1) + "┬" + "─" * (size_width + 1) + "┬" + "─" * (id_width + 1) + "╮")
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(f"│ {'User':<{user_width}}│ {'Status':<{status_width}}│ {'Attached To':<{attached_width}}│ {'Size':<{size_width}}│ {'Studio ID':<{id_width}}│")
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("├" + "─" * (user_width + 1) + "┼" + "─" * (status_width + 1) + "┼" + "─" * (attached_width + 1) + "┼" + "─" * (size_width + 1) + "┼" + "─" * (id_width + 1) + "┤")
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(f"{display_status:<{status_width}}", "35") # Purple
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(f"│ {user_display}│ {status_display}│ {attached_display}│ {size:<{size_width}}│ {studio_id_display}│")
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("╰" + "─" * (user_width + 1) + "┴" + "─" * (status_width + 1) + "┴" + "─" * (attached_width + 1) + "┴" + "─" * (size_width + 1) + "┴" + "─" * (id_width + 1) + "╯")
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(scenario_data["studios"], scenario_data["engines_map"], env)
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
- click.echo(f"Attached to: \033[34m{studio['attached_to']}\033[0m")
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((len(studio.get("user", "unknown")) for studio in studios), default=4)
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(max_attached_len + 2, len("Attached To") + 2, 3) # At least 3 for "-"
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("╭" + "─" * (user_width + 1) + "┬" + "─" * (status_width + 1) + "┬" + "─" * (attached_width + 1) + "┬" + "─" * (size_width + 1) + "┬" + "─" * (id_width + 1) + "╮")
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("├" + "─" * (user_width + 1) + "┼" + "─" * (status_width + 1) + "┼" + "─" * (attached_width + 1) + "┼" + "─" * (size_width + 1) + "┼" + "─" * (id_width + 1) + "┤")
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 = f"\033[35m{display_status:<{status_width}}\033[0m" # Purple
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 = f"\033[31m{status:<{status_width}}\033[0m" # Red for error
370
+ status_display = (
371
+ f"\033[31m{status:<{status_width}}\033[0m" # Red for error
372
+ )
330
373
  else:
331
- status_display = f"{status:<{status_width}}" # No color for other states
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("╰" + "─" * (user_width + 1) + "┴" + "─" * (status_width + 1) + "┴" + "─" * (attached_width + 1) + "┴" + "─" * (size_width + 1) + "┴" + "─" * (id_width + 1) + "╯")
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
 
@@ -5,7 +5,7 @@ build-backend = "poetry.core.masonry.api"
5
5
 
6
6
  [project]
7
7
  name = "dayhoff-tools"
8
- version = "1.13.8"
8
+ version = "1.13.10"
9
9
  description = "Common tools for all the repos at Dayhoff Labs"
10
10
  authors = [
11
11
  {name = "Daniel Martin-Alarcon", email = "dma@dayhofflabs.com"}