dayhoff-tools 1.3.22__tar.gz → 1.3.24__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 (32) hide show
  1. {dayhoff_tools-1.3.22 → dayhoff_tools-1.3.24}/PKG-INFO +1 -1
  2. {dayhoff_tools-1.3.22 → dayhoff_tools-1.3.24}/dayhoff_tools/cli/engine_commands.py +35 -83
  3. {dayhoff_tools-1.3.22 → dayhoff_tools-1.3.24}/pyproject.toml +1 -1
  4. {dayhoff_tools-1.3.22 → dayhoff_tools-1.3.24}/README.md +0 -0
  5. {dayhoff_tools-1.3.22 → dayhoff_tools-1.3.24}/dayhoff_tools/__init__.py +0 -0
  6. {dayhoff_tools-1.3.22 → dayhoff_tools-1.3.24}/dayhoff_tools/chemistry/standardizer.py +0 -0
  7. {dayhoff_tools-1.3.22 → dayhoff_tools-1.3.24}/dayhoff_tools/chemistry/utils.py +0 -0
  8. {dayhoff_tools-1.3.22 → dayhoff_tools-1.3.24}/dayhoff_tools/cli/__init__.py +0 -0
  9. {dayhoff_tools-1.3.22 → dayhoff_tools-1.3.24}/dayhoff_tools/cli/cloud_commands.py +0 -0
  10. {dayhoff_tools-1.3.22 → dayhoff_tools-1.3.24}/dayhoff_tools/cli/main.py +0 -0
  11. {dayhoff_tools-1.3.22 → dayhoff_tools-1.3.24}/dayhoff_tools/cli/swarm_commands.py +0 -0
  12. {dayhoff_tools-1.3.22 → dayhoff_tools-1.3.24}/dayhoff_tools/cli/utility_commands.py +0 -0
  13. {dayhoff_tools-1.3.22 → dayhoff_tools-1.3.24}/dayhoff_tools/deployment/base.py +0 -0
  14. {dayhoff_tools-1.3.22 → dayhoff_tools-1.3.24}/dayhoff_tools/deployment/deploy_aws.py +0 -0
  15. {dayhoff_tools-1.3.22 → dayhoff_tools-1.3.24}/dayhoff_tools/deployment/deploy_gcp.py +0 -0
  16. {dayhoff_tools-1.3.22 → dayhoff_tools-1.3.24}/dayhoff_tools/deployment/deploy_utils.py +0 -0
  17. {dayhoff_tools-1.3.22 → dayhoff_tools-1.3.24}/dayhoff_tools/deployment/job_runner.py +0 -0
  18. {dayhoff_tools-1.3.22 → dayhoff_tools-1.3.24}/dayhoff_tools/deployment/processors.py +0 -0
  19. {dayhoff_tools-1.3.22 → dayhoff_tools-1.3.24}/dayhoff_tools/deployment/swarm.py +0 -0
  20. {dayhoff_tools-1.3.22 → dayhoff_tools-1.3.24}/dayhoff_tools/embedders.py +0 -0
  21. {dayhoff_tools-1.3.22 → dayhoff_tools-1.3.24}/dayhoff_tools/fasta.py +0 -0
  22. {dayhoff_tools-1.3.22 → dayhoff_tools-1.3.24}/dayhoff_tools/file_ops.py +0 -0
  23. {dayhoff_tools-1.3.22 → dayhoff_tools-1.3.24}/dayhoff_tools/h5.py +0 -0
  24. {dayhoff_tools-1.3.22 → dayhoff_tools-1.3.24}/dayhoff_tools/intake/gcp.py +0 -0
  25. {dayhoff_tools-1.3.22 → dayhoff_tools-1.3.24}/dayhoff_tools/intake/gtdb.py +0 -0
  26. {dayhoff_tools-1.3.22 → dayhoff_tools-1.3.24}/dayhoff_tools/intake/kegg.py +0 -0
  27. {dayhoff_tools-1.3.22 → dayhoff_tools-1.3.24}/dayhoff_tools/intake/mmseqs.py +0 -0
  28. {dayhoff_tools-1.3.22 → dayhoff_tools-1.3.24}/dayhoff_tools/intake/structure.py +0 -0
  29. {dayhoff_tools-1.3.22 → dayhoff_tools-1.3.24}/dayhoff_tools/intake/uniprot.py +0 -0
  30. {dayhoff_tools-1.3.22 → dayhoff_tools-1.3.24}/dayhoff_tools/logs.py +0 -0
  31. {dayhoff_tools-1.3.22 → dayhoff_tools-1.3.24}/dayhoff_tools/sqlite.py +0 -0
  32. {dayhoff_tools-1.3.22 → dayhoff_tools-1.3.24}/dayhoff_tools/warehouse.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: dayhoff-tools
3
- Version: 1.3.22
3
+ Version: 1.3.24
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
@@ -532,7 +532,6 @@ def list_engines(
532
532
  table.add_column("Type")
533
533
  table.add_column("User")
534
534
  table.add_column("Status")
535
- table.add_column("Stage")
536
535
  table.add_column("Disk Usage")
537
536
  table.add_column("Uptime/Since")
538
537
  table.add_column("$/hour", justify="right")
@@ -555,15 +554,12 @@ def list_engines(
555
554
  time_str = launch_time.strftime("%Y-%m-%d %H:%M")
556
555
  disk_usage = "-"
557
556
 
558
- stage_display = _colour_stage(stages_map.get(engine["instance_id"], "-"))
559
-
560
557
  table.add_row(
561
558
  engine["name"],
562
559
  engine["instance_id"],
563
560
  engine["engine_type"],
564
561
  engine["user"],
565
562
  format_status(engine["state"], engine.get("ready")),
566
- stage_display,
567
563
  disk_usage,
568
564
  time_str,
569
565
  f"${hourly_cost:.2f}",
@@ -831,7 +827,7 @@ def ssh_engine(
831
827
  raise typer.Exit(1)
832
828
 
833
829
  # Choose SSH user
834
- ssh_user = "ec2-user" if admin else engine["user"]
830
+ ssh_user = "ec2-user" if admin else username
835
831
 
836
832
  # Update SSH config
837
833
  console.print(f"Updating SSH config for [cyan]{engine['name']}[/cyan] (user: {ssh_user})...")
@@ -908,7 +904,7 @@ def config_ssh(
908
904
  if not clean:
909
905
  for engine in running_engines:
910
906
  # Determine ssh user based on --admin flag
911
- ssh_user = 'ec2-user' if admin else engine['user']
907
+ ssh_user = 'ec2-user' if admin else username
912
908
  new_lines.extend(
913
909
  [
914
910
  "",
@@ -938,26 +934,31 @@ def config_ssh(
938
934
  )
939
935
 
940
936
 
941
- @engine_app.command("keep-awake")
942
- def keep_awake(
937
+ @engine_app.command("coffee")
938
+ def coffee(
943
939
  name_or_id: str = typer.Argument(help="Engine name or instance ID"),
944
- duration: str = typer.Argument("4h", help="Duration (e.g., 2h, 30m, 4h30m)"),
940
+ duration: str = typer.Argument("4h", help="Duration (e.g., 2h, 30m, 2h30m)"),
941
+ cancel: bool = typer.Option(False, "--cancel", help="Cancel existing coffee lock instead of extending"),
945
942
  ):
946
- """Prevent an engine from auto-shutting down."""
943
+ """Pour ☕ for an engine: keeps it awake for the given duration (or cancel)."""
947
944
  username = check_aws_sso()
948
945
 
949
946
  # Parse duration
950
947
  import re
951
948
 
952
- match = re.match(r"(?:(\d+)h)?(?:(\d+)m)?", duration)
953
- if not match or (not match.group(1) and not match.group(2)):
954
- console.print(f"[red]❌ Invalid duration format: {duration}[/red]")
955
- console.print("Use format like: 4h, 30m, 2h30m")
956
- raise typer.Exit(1)
949
+ if not cancel:
950
+ match = re.match(r"(?:(\d+)h)?(?:(\d+)m)?", duration)
951
+ if not match or (not match.group(1) and not match.group(2)):
952
+ console.print(f"[red]❌ Invalid duration format: {duration}[/red]")
953
+ console.print("Use format like: 4h, 30m, 2h30m")
954
+ raise typer.Exit(1)
957
955
 
958
- hours = int(match.group(1) or 0)
959
- minutes = int(match.group(2) or 0)
960
- total_minutes = hours * 60 + minutes
956
+ hours = int(match.group(1) or 0)
957
+ minutes = int(match.group(2) or 0)
958
+ seconds_total = (hours * 60 + minutes) * 60
959
+ if seconds_total == 0:
960
+ console.print("[red]❌ Duration must be greater than zero[/red]")
961
+ raise typer.Exit(1)
961
962
 
962
963
  # Get all engines to resolve name
963
964
  response = make_api_request("GET", "/engines")
@@ -972,9 +973,10 @@ def keep_awake(
972
973
  console.print(f"[red]❌ Engine is not running (state: {engine['state']})[/red]")
973
974
  raise typer.Exit(1)
974
975
 
975
- console.print(
976
- f"Setting keep-awake for [cyan]{engine['name']}[/cyan] for {duration}..."
977
- )
976
+ if cancel:
977
+ console.print(f"Cancelling coffee for [cyan]{engine['name']}[/cyan]")
978
+ else:
979
+ console.print(f"Pouring coffee for [cyan]{engine['name']}[/cyan] for {duration}…")
978
980
 
979
981
  # Use SSM to run the engine keep-alive command
980
982
  ssm = boto3.client("ssm", region_name="us-east-1")
@@ -983,7 +985,9 @@ def keep_awake(
983
985
  InstanceIds=[engine["instance_id"]],
984
986
  DocumentName="AWS-RunShellScript",
985
987
  Parameters={
986
- "commands": [f"engine keep-alive {duration}"],
988
+ "commands": [
989
+ ("engine-coffee --cancel" if cancel else f"engine-coffee {seconds_total}")
990
+ ],
987
991
  "executionTimeout": ["60"],
988
992
  },
989
993
  )
@@ -1001,75 +1005,23 @@ def keep_awake(
1001
1005
  break
1002
1006
 
1003
1007
  if result["Status"] == "Success":
1004
- console.print(f"[green]✓ Engine will stay awake for {duration}[/green]")
1008
+ if cancel:
1009
+ console.print("[green]✓ Coffee cancelled – auto-shutdown re-enabled[/green]")
1010
+ else:
1011
+ console.print(f"[green]✓ Coffee poured for {duration}[/green]")
1005
1012
  console.print(
1006
1013
  "\n[dim]Note: Detached Docker containers (except dev containers) will also keep the engine awake.[/dim]"
1007
1014
  )
1008
1015
  console.print(
1009
- "[dim]Use keep-awake for nohup operations or other background tasks.[/dim]"
1010
- )
1011
- else:
1012
- console.print(
1013
- f"[red]❌ Failed to set keep-awake: {result.get('StatusDetails', 'Unknown error')}[/red]"
1014
- )
1015
-
1016
- except ClientError as e:
1017
- console.print(f"[red]❌ Failed to set keep-awake: {e}[/red]")
1018
-
1019
-
1020
- @engine_app.command("cancel-keep-awake")
1021
- def cancel_keep_awake(
1022
- name_or_id: str = typer.Argument(help="Engine name or instance ID"),
1023
- ):
1024
- """Cancel keep-awake and re-enable auto-shutdown."""
1025
- username = check_aws_sso()
1026
-
1027
- # Get all engines to resolve name
1028
- response = make_api_request("GET", "/engines")
1029
- if response.status_code != 200:
1030
- console.print("[red]❌ Failed to fetch engines[/red]")
1031
- raise typer.Exit(1)
1032
-
1033
- engines = response.json().get("engines", [])
1034
- engine = resolve_engine(name_or_id, engines)
1035
-
1036
- console.print(f"Cancelling keep-awake for [cyan]{engine['name']}[/cyan]...")
1037
-
1038
- # Use SSM to run the engine cancel command
1039
- ssm = boto3.client("ssm", region_name="us-east-1")
1040
- try:
1041
- response = ssm.send_command(
1042
- InstanceIds=[engine["instance_id"]],
1043
- DocumentName="AWS-RunShellScript",
1044
- Parameters={
1045
- "commands": ["engine cancel"],
1046
- "executionTimeout": ["60"],
1047
- },
1048
- )
1049
-
1050
- command_id = response["Command"]["CommandId"]
1051
-
1052
- # Wait for command to complete
1053
- for _ in range(10):
1054
- time.sleep(1)
1055
- result = ssm.get_command_invocation(
1056
- CommandId=command_id,
1057
- InstanceId=engine["instance_id"],
1058
- )
1059
- if result["Status"] in ["Success", "Failed"]:
1060
- break
1061
-
1062
- if result["Status"] == "Success":
1063
- console.print(
1064
- "[green]✓ Keep-awake cancelled, auto-shutdown re-enabled[/green]"
1016
+ "[dim]Use coffee for nohup operations or other background tasks.[/dim]"
1065
1017
  )
1066
1018
  else:
1067
1019
  console.print(
1068
- f"[red]❌ Failed to cancel keep-awake: {result.get('StatusDetails', 'Unknown error')}[/red]"
1020
+ f"[red]❌ Failed to manage coffee: {result.get('StatusDetails', 'Unknown error')}[/red]"
1069
1021
  )
1070
1022
 
1071
1023
  except ClientError as e:
1072
- console.print(f"[red]❌ Failed to cancel keep-awake: {e}[/red]")
1024
+ console.print(f"[red]❌ Failed to manage coffee: {e}[/red]")
1073
1025
 
1074
1026
 
1075
1027
  @engine_app.command("resize")
@@ -1233,7 +1185,7 @@ def resize_engine(
1233
1185
  raise typer.Exit(1)
1234
1186
 
1235
1187
 
1236
- @engine_app.command("create-ami")
1188
+ @engine_app.command("gami")
1237
1189
  def create_ami(
1238
1190
  name_or_id: str = typer.Argument(
1239
1191
  help="Engine name or instance ID to create AMI from"
@@ -2011,7 +1963,7 @@ def resize_studio(
2011
1963
  # ================= Idle timeout command =================
2012
1964
 
2013
1965
 
2014
- @engine_app.command("idle-timeout")
1966
+ @engine_app.command("idle")
2015
1967
  def idle_timeout_cmd(
2016
1968
  name_or_id: str = typer.Argument(help="Engine name or instance ID"),
2017
1969
  set: Optional[str] = typer.Option(None, "--set", "-s", help="New timeout (e.g., 2h30m, 45m)")
@@ -5,7 +5,7 @@ build-backend = "poetry.core.masonry.api"
5
5
 
6
6
  [project]
7
7
  name = "dayhoff-tools"
8
- version = "1.3.22"
8
+ version = "1.3.24"
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