dayhoff-tools 1.5.8__py3-none-any.whl → 1.6.0__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.

Potentially problematic release.


This version of dayhoff-tools might be problematic. Click here for more details.

@@ -409,37 +409,35 @@ def update_ssh_config_entry(engine_name: str, instance_id: str, ssh_user: str, i
409
409
 
410
410
  # Read existing config
411
411
  content = config_path.read_text()
412
+ lines = content.splitlines() if content else []
412
413
 
413
- # Create new entry
414
- new_entry = f"""
415
- Host {engine_name} {SSH_MANAGED_COMMENT}
416
- HostName {instance_id}
417
- User {ssh_user}
418
- ProxyCommand sh -c \"AWS_SSM_IDLE_TIMEOUT={idle_timeout} aws ssm start-session --target %h --document-name AWS-StartSSHSession --parameters 'portNumber=%p'\"\n"""
419
-
420
- # Check if entry already exists
421
- host_line = f"Host {engine_name} {SSH_MANAGED_COMMENT}"
422
- if host_line in content:
423
- # Update existing entry
424
- lines = content.splitlines()
425
- new_lines = []
426
- skip_count = 0
427
- for line in lines:
428
- if line.strip() == host_line.strip():
429
- new_lines.extend(new_entry.strip().splitlines())
430
- skip_count = 4 # Skip the next 4 lines (old entry)
431
- elif skip_count > 0:
432
- skip_count -= 1
433
- continue
434
- else:
435
- new_lines.append(line)
436
- content = "\n".join(new_lines)
437
- else:
438
- # Append new entry
439
- content = content.rstrip() + "\n" + new_entry
414
+ # Remove any existing entry for this engine
415
+ new_lines = []
416
+ skip_until_next_host = False
417
+ for line in lines:
418
+ # Check if this is our managed host
419
+ if line.strip().startswith(f"Host {engine_name}") and SSH_MANAGED_COMMENT in line:
420
+ skip_until_next_host = True
421
+ elif line.strip().startswith("Host ") and skip_until_next_host:
422
+ skip_until_next_host = False
423
+ # This is a different host entry, keep it
424
+ new_lines.append(line)
425
+ elif not skip_until_next_host:
426
+ new_lines.append(line)
427
+
428
+ # Add the new entry
429
+ if new_lines and new_lines[-1].strip(): # Add blank line if needed
430
+ new_lines.append("")
431
+
432
+ new_lines.extend([
433
+ f"Host {engine_name} {SSH_MANAGED_COMMENT}",
434
+ f" HostName {instance_id}",
435
+ f" User {ssh_user}",
436
+ f" ProxyCommand sh -c \"AWS_SSM_IDLE_TIMEOUT={idle_timeout} aws ssm start-session --target %h --document-name AWS-StartSSHSession --parameters 'portNumber=%p'\"",
437
+ ])
440
438
 
441
439
  # Write back
442
- config_path.write_text(content)
440
+ config_path.write_text("\n".join(new_lines))
443
441
  config_path.chmod(0o600)
444
442
 
445
443
 
@@ -547,6 +545,9 @@ def list_engines(
547
545
  stopped_only: bool = typer.Option(
548
546
  False, "--stopped", help="Show only stopped engines"
549
547
  ),
548
+ detailed: bool = typer.Option(
549
+ False, "--detailed", "-d", help="Show detailed status (slower)"
550
+ ),
550
551
  ):
551
552
  """List engines (shows all engines by default)."""
552
553
  current_user = check_aws_sso()
@@ -554,6 +555,8 @@ def list_engines(
554
555
  params = {}
555
556
  if user:
556
557
  params["user"] = user
558
+ if detailed:
559
+ params["check_ready"] = "true"
557
560
 
558
561
  response = make_api_request("GET", "/engines", params=params)
559
562
 
@@ -571,8 +574,10 @@ def list_engines(
571
574
  console.print("No engines found.")
572
575
  return
573
576
 
574
- # Fetch bootstrap stages once
575
- stages_map = _fetch_init_stages([e["instance_id"] for e in engines])
577
+ # Only fetch detailed info if requested (slow)
578
+ stages_map = {}
579
+ if detailed:
580
+ stages_map = _fetch_init_stages([e["instance_id"] for e in engines])
576
581
 
577
582
  # Create table
578
583
  table = Table(title="Engines", box=box.ROUNDED)
@@ -581,7 +586,8 @@ def list_engines(
581
586
  table.add_column("Type")
582
587
  table.add_column("User")
583
588
  table.add_column("Status")
584
- table.add_column("Disk Usage")
589
+ if detailed:
590
+ table.add_column("Disk Usage")
585
591
  table.add_column("Uptime/Since")
586
592
  table.add_column("$/hour", justify="right")
587
593
 
@@ -592,24 +598,34 @@ def list_engines(
592
598
 
593
599
  if engine["state"].lower() == "running":
594
600
  time_str = format_duration(uptime)
595
- # Get disk usage for running engines
596
- disk_usage = get_disk_usage_via_ssm(engine["instance_id"]) or "-"
601
+ # Only get disk usage if detailed mode
602
+ if detailed:
603
+ disk_usage = get_disk_usage_via_ssm(engine["instance_id"]) or "-"
604
+ else:
605
+ disk_usage = None
597
606
  else:
598
607
  time_str = launch_time.strftime("%Y-%m-%d %H:%M")
599
- disk_usage = "-"
608
+ disk_usage = "-" if detailed else None
600
609
 
601
- table.add_row(
610
+ row_data = [
602
611
  engine["name"],
603
612
  engine["instance_id"],
604
613
  engine["engine_type"],
605
614
  engine["user"],
606
615
  format_status(engine["state"], engine.get("ready")),
607
- disk_usage,
616
+ ]
617
+ if detailed:
618
+ row_data.append(disk_usage)
619
+ row_data.extend([
608
620
  time_str,
609
621
  f"${hourly_cost:.2f}",
610
- )
622
+ ])
623
+
624
+ table.add_row(*row_data)
611
625
 
612
626
  console.print(table)
627
+ if not detailed and any(e["state"].lower() == "running" for e in engines):
628
+ console.print("\n[dim]Tip: Use --detailed to see disk usage and bootstrap status (slower)[/dim]")
613
629
  else:
614
630
  error = response.json().get("error", "Unknown error")
615
631
  console.print(f"[red]❌ Failed to list engines: {error}[/red]")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: dayhoff-tools
3
- Version: 1.5.8
3
+ Version: 1.6.0
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
@@ -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=oY291nhCsU470Alol8VxXn_e2fbB7ykXFayH3AICK9g,96371
6
+ dayhoff_tools/cli/engine_commands.py,sha256=RSbZK2hN3bTBQrZxAgooqMsqSiw0hnhmzTVkL44xdD4,97147
7
7
  dayhoff_tools/cli/main.py,sha256=tRN7WCBHg6uyNp6rA54pKTCoVmBntta2i0Yas3bUpZ4,4853
8
8
  dayhoff_tools/cli/swarm_commands.py,sha256=5EyKj8yietvT5lfoz8Zx0iQvVaNgc3SJX1z2zQR6o6M,5614
9
9
  dayhoff_tools/cli/utility_commands.py,sha256=FRZTPrjsG_qmIIqoNxd1Q1vVkS_5w8aY33IrVYVNCLg,18131
@@ -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=heaYc64qplgN3_1WVPFmqj53goStioWwY5NqlWc4c0s,24453
30
- dayhoff_tools-1.5.8.dist-info/METADATA,sha256=M5694yUrFz-O9IfiuxskFZZae8mXnJ5xA1GiRJfHHJQ,2914
31
- dayhoff_tools-1.5.8.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
32
- dayhoff_tools-1.5.8.dist-info/entry_points.txt,sha256=iAf4jteNqW3cJm6CO6czLxjW3vxYKsyGLZ8WGmxamSc,49
33
- dayhoff_tools-1.5.8.dist-info/RECORD,,
30
+ dayhoff_tools-1.6.0.dist-info/METADATA,sha256=aXQi1sUTKyyRPmViY6r7pWBnTaTDV2v8krFQK1wLvNY,2914
31
+ dayhoff_tools-1.6.0.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
32
+ dayhoff_tools-1.6.0.dist-info/entry_points.txt,sha256=iAf4jteNqW3cJm6CO6czLxjW3vxYKsyGLZ8WGmxamSc,49
33
+ dayhoff_tools-1.6.0.dist-info/RECORD,,