dayhoff-tools 1.9.13__tar.gz → 1.9.15__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 (38) hide show
  1. {dayhoff_tools-1.9.13 → dayhoff_tools-1.9.15}/PKG-INFO +1 -1
  2. {dayhoff_tools-1.9.13 → dayhoff_tools-1.9.15}/dayhoff_tools/cli/engine/__init__.py +38 -6
  3. {dayhoff_tools-1.9.13 → dayhoff_tools-1.9.15}/dayhoff_tools/cli/engine/engine_maintenance.py +34 -30
  4. {dayhoff_tools-1.9.13 → dayhoff_tools-1.9.15}/pyproject.toml +1 -1
  5. {dayhoff_tools-1.9.13 → dayhoff_tools-1.9.15}/README.md +0 -0
  6. {dayhoff_tools-1.9.13 → dayhoff_tools-1.9.15}/dayhoff_tools/__init__.py +0 -0
  7. {dayhoff_tools-1.9.13 → dayhoff_tools-1.9.15}/dayhoff_tools/chemistry/standardizer.py +0 -0
  8. {dayhoff_tools-1.9.13 → dayhoff_tools-1.9.15}/dayhoff_tools/chemistry/utils.py +0 -0
  9. {dayhoff_tools-1.9.13 → dayhoff_tools-1.9.15}/dayhoff_tools/cli/__init__.py +0 -0
  10. {dayhoff_tools-1.9.13 → dayhoff_tools-1.9.15}/dayhoff_tools/cli/cloud_commands.py +0 -0
  11. {dayhoff_tools-1.9.13 → dayhoff_tools-1.9.15}/dayhoff_tools/cli/engine/engine_core.py +0 -0
  12. {dayhoff_tools-1.9.13 → dayhoff_tools-1.9.15}/dayhoff_tools/cli/engine/engine_lifecycle.py +0 -0
  13. {dayhoff_tools-1.9.13 → dayhoff_tools-1.9.15}/dayhoff_tools/cli/engine/engine_management.py +0 -0
  14. {dayhoff_tools-1.9.13 → dayhoff_tools-1.9.15}/dayhoff_tools/cli/engine/shared.py +0 -0
  15. {dayhoff_tools-1.9.13 → dayhoff_tools-1.9.15}/dayhoff_tools/cli/engine/studio_commands.py +0 -0
  16. {dayhoff_tools-1.9.13 → dayhoff_tools-1.9.15}/dayhoff_tools/cli/main.py +0 -0
  17. {dayhoff_tools-1.9.13 → dayhoff_tools-1.9.15}/dayhoff_tools/cli/swarm_commands.py +0 -0
  18. {dayhoff_tools-1.9.13 → dayhoff_tools-1.9.15}/dayhoff_tools/cli/utility_commands.py +0 -0
  19. {dayhoff_tools-1.9.13 → dayhoff_tools-1.9.15}/dayhoff_tools/deployment/base.py +0 -0
  20. {dayhoff_tools-1.9.13 → dayhoff_tools-1.9.15}/dayhoff_tools/deployment/deploy_aws.py +0 -0
  21. {dayhoff_tools-1.9.13 → dayhoff_tools-1.9.15}/dayhoff_tools/deployment/deploy_gcp.py +0 -0
  22. {dayhoff_tools-1.9.13 → dayhoff_tools-1.9.15}/dayhoff_tools/deployment/deploy_utils.py +0 -0
  23. {dayhoff_tools-1.9.13 → dayhoff_tools-1.9.15}/dayhoff_tools/deployment/job_runner.py +0 -0
  24. {dayhoff_tools-1.9.13 → dayhoff_tools-1.9.15}/dayhoff_tools/deployment/processors.py +0 -0
  25. {dayhoff_tools-1.9.13 → dayhoff_tools-1.9.15}/dayhoff_tools/deployment/swarm.py +0 -0
  26. {dayhoff_tools-1.9.13 → dayhoff_tools-1.9.15}/dayhoff_tools/embedders.py +0 -0
  27. {dayhoff_tools-1.9.13 → dayhoff_tools-1.9.15}/dayhoff_tools/fasta.py +0 -0
  28. {dayhoff_tools-1.9.13 → dayhoff_tools-1.9.15}/dayhoff_tools/file_ops.py +0 -0
  29. {dayhoff_tools-1.9.13 → dayhoff_tools-1.9.15}/dayhoff_tools/h5.py +0 -0
  30. {dayhoff_tools-1.9.13 → dayhoff_tools-1.9.15}/dayhoff_tools/intake/gcp.py +0 -0
  31. {dayhoff_tools-1.9.13 → dayhoff_tools-1.9.15}/dayhoff_tools/intake/gtdb.py +0 -0
  32. {dayhoff_tools-1.9.13 → dayhoff_tools-1.9.15}/dayhoff_tools/intake/kegg.py +0 -0
  33. {dayhoff_tools-1.9.13 → dayhoff_tools-1.9.15}/dayhoff_tools/intake/mmseqs.py +0 -0
  34. {dayhoff_tools-1.9.13 → dayhoff_tools-1.9.15}/dayhoff_tools/intake/structure.py +0 -0
  35. {dayhoff_tools-1.9.13 → dayhoff_tools-1.9.15}/dayhoff_tools/intake/uniprot.py +0 -0
  36. {dayhoff_tools-1.9.13 → dayhoff_tools-1.9.15}/dayhoff_tools/logs.py +0 -0
  37. {dayhoff_tools-1.9.13 → dayhoff_tools-1.9.15}/dayhoff_tools/sqlite.py +0 -0
  38. {dayhoff_tools-1.9.13 → dayhoff_tools-1.9.15}/dayhoff_tools/warehouse.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: dayhoff-tools
3
- Version: 1.9.13
3
+ Version: 1.9.15
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
@@ -1,5 +1,7 @@
1
1
  """Engine and Studio management commands for DHT CLI."""
2
2
 
3
+ from typing import Optional
4
+
3
5
  import typer
4
6
 
5
7
  # Initialize Typer apps
@@ -9,6 +11,7 @@ studio_app = typer.Typer(help="Manage persistent development studios.")
9
11
  # Use lazy loading pattern similar to main.py swarm commands
10
12
  # Import functions only when commands are actually called
11
13
 
14
+
12
15
  # Engine commands
13
16
  @engine_app.command("launch")
14
17
  def launch_engine_cmd(
@@ -34,6 +37,7 @@ def launch_engine_cmd(
34
37
  ):
35
38
  """Launch a new engine instance."""
36
39
  from .engine_core import launch_engine
40
+
37
41
  return launch_engine(name, engine_type, user, boot_disk_size, availability_zone)
38
42
 
39
43
 
@@ -52,17 +56,23 @@ def list_engines_cmd(
52
56
  ):
53
57
  """List engines (shows all engines by default)."""
54
58
  from .engine_core import list_engines
59
+
55
60
  return list_engines(user, running_only, stopped_only, detailed)
56
61
 
57
62
 
58
63
  @engine_app.command("status")
59
64
  def engine_status_cmd(
60
65
  name_or_id: str = typer.Argument(help="Engine name or instance ID"),
61
- detailed: bool = typer.Option(False, "--detailed", "-d", help="Show detailed status (slower)"),
62
- show_log: bool = typer.Option(False, "--show-log", help="Show bootstrap log (requires --detailed)"),
66
+ detailed: bool = typer.Option(
67
+ False, "--detailed", "-d", help="Show detailed status (slower)"
68
+ ),
69
+ show_log: bool = typer.Option(
70
+ False, "--show-log", help="Show bootstrap log (requires --detailed)"
71
+ ),
63
72
  ):
64
73
  """Show engine status and information."""
65
74
  from .engine_core import engine_status
75
+
66
76
  return engine_status(name_or_id, detailed, show_log)
67
77
 
68
78
 
@@ -72,6 +82,7 @@ def start_engine_cmd(
72
82
  ):
73
83
  """Start a stopped engine."""
74
84
  from .engine_lifecycle import start_engine
85
+
75
86
  return start_engine(name_or_id)
76
87
 
77
88
 
@@ -84,6 +95,7 @@ def stop_engine_cmd(
84
95
  ):
85
96
  """Stop an engine."""
86
97
  from .engine_lifecycle import stop_engine
98
+
87
99
  return stop_engine(name_or_id, force)
88
100
 
89
101
 
@@ -93,6 +105,7 @@ def terminate_engine_cmd(
93
105
  ):
94
106
  """Permanently terminate an engine."""
95
107
  from .engine_lifecycle import terminate_engine
108
+
96
109
  return terminate_engine(name_or_id)
97
110
 
98
111
 
@@ -110,6 +123,7 @@ def ssh_engine_cmd(
110
123
  ):
111
124
  """Connect to an engine via SSH."""
112
125
  from .engine_management import ssh_engine
126
+
113
127
  return ssh_engine(name_or_id, admin, idle_timeout)
114
128
 
115
129
 
@@ -127,6 +141,7 @@ def config_ssh_cmd(
127
141
  ):
128
142
  """Update SSH config with available engines."""
129
143
  from .engine_management import config_ssh
144
+
130
145
  return config_ssh(clean, all_engines, admin)
131
146
 
132
147
 
@@ -145,6 +160,7 @@ def resize_engine_cmd(
145
160
  ):
146
161
  """Resize an engine's boot disk."""
147
162
  from .engine_management import resize_engine
163
+
148
164
  return resize_engine(name_or_id, size, online, force)
149
165
 
150
166
 
@@ -156,6 +172,7 @@ def create_ami_cmd(
156
172
  ):
157
173
  """Create a 'Golden AMI' from a running engine."""
158
174
  from .engine_management import create_ami
175
+
159
176
  return create_ami(name_or_id)
160
177
 
161
178
 
@@ -169,19 +186,24 @@ def coffee_cmd(
169
186
  ):
170
187
  """Pour ☕ for an engine: keeps it awake for the given duration (or cancel)."""
171
188
  from .engine_maintenance import coffee
189
+
172
190
  return coffee(name_or_id, duration, cancel)
173
191
 
174
192
 
175
193
  @engine_app.command("idle")
176
194
  def idle_timeout_cmd_wrapper(
177
195
  name_or_id: str = typer.Argument(help="Engine name or instance ID"),
178
- set: str = typer.Option(
196
+ set: Optional[str] = typer.Option(
179
197
  None, "--set", "-s", help="New timeout (e.g., 2h30m, 45m)"
180
198
  ),
199
+ slack: Optional[str] = typer.Option(
200
+ None, "--slack", help="Set Slack notifications: none, default, all"
201
+ ),
181
202
  ):
182
- """Show or set the engine idle-detector timeout."""
203
+ """Show or set engine idle-detector settings."""
183
204
  from .engine_maintenance import idle_timeout_cmd
184
- return idle_timeout_cmd(name_or_id, set)
205
+
206
+ return idle_timeout_cmd(name_or_id=name_or_id, set=set, slack=slack)
185
207
 
186
208
 
187
209
  @engine_app.command("debug")
@@ -190,6 +212,7 @@ def debug_engine_cmd(
190
212
  ):
191
213
  """Debug engine bootstrap status and files."""
192
214
  from .engine_maintenance import debug_engine
215
+
193
216
  return debug_engine(name_or_id)
194
217
 
195
218
 
@@ -199,6 +222,7 @@ def repair_engine_cmd(
199
222
  ):
200
223
  """Repair an engine that's stuck in a bad state (e.g., after GAMI creation)."""
201
224
  from .engine_maintenance import repair_engine
225
+
202
226
  return repair_engine(name_or_id)
203
227
 
204
228
 
@@ -209,6 +233,7 @@ def create_studio_cmd(
209
233
  ):
210
234
  """Create a new studio for the current user."""
211
235
  from .studio_commands import create_studio
236
+
212
237
  return create_studio(size_gb)
213
238
 
214
239
 
@@ -220,6 +245,7 @@ def studio_status_cmd(
220
245
  ):
221
246
  """Show status of your studio."""
222
247
  from .studio_commands import studio_status
248
+
223
249
  return studio_status(user)
224
250
 
225
251
 
@@ -232,6 +258,7 @@ def attach_studio_cmd(
232
258
  ):
233
259
  """Attach your studio to an engine."""
234
260
  from .studio_commands import attach_studio
261
+
235
262
  return attach_studio(engine_name_or_id, user)
236
263
 
237
264
 
@@ -243,6 +270,7 @@ def detach_studio_cmd(
243
270
  ):
244
271
  """Detach your studio from its current engine."""
245
272
  from .studio_commands import detach_studio
273
+
246
274
  return detach_studio(user)
247
275
 
248
276
 
@@ -254,6 +282,7 @@ def delete_studio_cmd(
254
282
  ):
255
283
  """Delete your studio permanently."""
256
284
  from .studio_commands import delete_studio
285
+
257
286
  return delete_studio(user)
258
287
 
259
288
 
@@ -265,6 +294,7 @@ def list_studios_cmd(
265
294
  ):
266
295
  """List studios."""
267
296
  from .studio_commands import list_studios
297
+
268
298
  return list_studios(all_users)
269
299
 
270
300
 
@@ -276,6 +306,7 @@ def reset_studio_cmd(
276
306
  ):
277
307
  """Reset a stuck studio (admin operation)."""
278
308
  from .studio_commands import reset_studio
309
+
279
310
  return reset_studio(user)
280
311
 
281
312
 
@@ -288,4 +319,5 @@ def resize_studio_cmd(
288
319
  ):
289
320
  """Resize your studio volume (requires detachment)."""
290
321
  from .studio_commands import resize_studio
291
- return resize_studio(size, user)
322
+
323
+ return resize_studio(size, user)
@@ -185,7 +185,40 @@ def idle_timeout_cmd(
185
185
  time.sleep(2) # Give it a moment to process
186
186
  console.print(f"[green]✓ Slack notifications updated to '{slack}'[/green]")
187
187
 
188
- if set is None and not slack:
188
+ # Handle setting new timeout value
189
+ if set is not None:
190
+ m = re.match(r"^(?:(\\d+)h)?(?:(\\d+)m)?$", set)
191
+ if not m:
192
+ console.print(
193
+ "[red]❌ Invalid duration format. Use e.g. 2h, 45m, 1h30m[/red]"
194
+ )
195
+ raise typer.Exit(1)
196
+ hours = int(m.group(1) or 0)
197
+ minutes = int(m.group(2) or 0)
198
+ seconds = hours * 3600 + minutes * 60
199
+ if seconds == 0:
200
+ console.print("[red]❌ Duration must be greater than zero[/red]")
201
+ raise typer.Exit(1)
202
+
203
+ console.print(f"Setting idle timeout to {set} ({seconds} seconds)…")
204
+
205
+ cmd = (
206
+ "sudo sed -i '/^IDLE_TIMEOUT_SECONDS=/d' /etc/engine.env && "
207
+ f"echo 'IDLE_TIMEOUT_SECONDS={seconds}' | sudo tee -a /etc/engine.env >/dev/null && "
208
+ "sudo systemctl restart engine-idle-detector.service"
209
+ )
210
+
211
+ resp = ssm.send_command(
212
+ InstanceIds=[engine["instance_id"]],
213
+ DocumentName="AWS-RunShellScript",
214
+ Parameters={"commands": [cmd], "executionTimeout": ["60"]},
215
+ )
216
+ cid = resp["Command"]["CommandId"]
217
+ time.sleep(2)
218
+ console.print(f"[green]✓ Idle timeout updated to {set}[/green]")
219
+
220
+ # If no action was specified, show current timeout
221
+ if set is None and slack is None:
189
222
  # Show current timeout setting
190
223
  resp = ssm.send_command(
191
224
  InstanceIds=[engine["instance_id"]],
@@ -210,35 +243,6 @@ def idle_timeout_cmd(
210
243
  console.print("[red]❌ Could not retrieve idle timeout[/red]")
211
244
  return
212
245
 
213
- # ----- set new value for timeout -----
214
- m = re.match(r"^(?:(\d+)h)?(?:(\d+)m)?$", set)
215
- if not m:
216
- console.print("[red]❌ Invalid duration format. Use e.g. 2h, 45m, 1h30m[/red]")
217
- raise typer.Exit(1)
218
- hours = int(m.group(1) or 0)
219
- minutes = int(m.group(2) or 0)
220
- seconds = hours * 3600 + minutes * 60
221
- if seconds == 0:
222
- console.print("[red]❌ Duration must be greater than zero[/red]")
223
- raise typer.Exit(1)
224
-
225
- console.print(f"Setting idle timeout to {set} ({seconds} seconds)…")
226
-
227
- cmd = (
228
- "sudo sed -i '/^IDLE_TIMEOUT_SECONDS=/d' /etc/engine.env && "
229
- f"echo 'IDLE_TIMEOUT_SECONDS={seconds}' | sudo tee -a /etc/engine.env >/dev/null && "
230
- "sudo systemctl restart engine-idle-detector.service"
231
- )
232
-
233
- resp = ssm.send_command(
234
- InstanceIds=[engine["instance_id"]],
235
- DocumentName="AWS-RunShellScript",
236
- Parameters={"commands": [cmd], "executionTimeout": ["60"]},
237
- )
238
- cid = resp["Command"]["CommandId"]
239
- time.sleep(2)
240
- console.print(f"[green]✓ Idle timeout updated to {set}[/green]")
241
-
242
246
 
243
247
  def debug_engine(
244
248
  name_or_id: str = typer.Argument(help="Engine name or instance ID"),
@@ -5,7 +5,7 @@ build-backend = "poetry.core.masonry.api"
5
5
 
6
6
  [project]
7
7
  name = "dayhoff-tools"
8
- version = "1.9.13"
8
+ version = "1.9.15"
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"}
File without changes