dayhoff-tools 1.3.23__py3-none-any.whl → 1.3.25__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.
@@ -934,26 +934,31 @@ def config_ssh(
934
934
  )
935
935
 
936
936
 
937
- @engine_app.command("keep-awake")
938
- def keep_awake(
937
+ @engine_app.command("coffee")
938
+ def coffee(
939
939
  name_or_id: str = typer.Argument(help="Engine name or instance ID"),
940
- 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"),
941
942
  ):
942
- """Prevent an engine from auto-shutting down."""
943
+ """Pour ☕ for an engine: keeps it awake for the given duration (or cancel)."""
943
944
  username = check_aws_sso()
944
945
 
945
946
  # Parse duration
946
947
  import re
947
948
 
948
- match = re.match(r"(?:(\d+)h)?(?:(\d+)m)?", duration)
949
- if not match or (not match.group(1) and not match.group(2)):
950
- console.print(f"[red]❌ Invalid duration format: {duration}[/red]")
951
- console.print("Use format like: 4h, 30m, 2h30m")
952
- 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)
953
955
 
954
- hours = int(match.group(1) or 0)
955
- minutes = int(match.group(2) or 0)
956
- 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)
957
962
 
958
963
  # Get all engines to resolve name
959
964
  response = make_api_request("GET", "/engines")
@@ -968,9 +973,10 @@ def keep_awake(
968
973
  console.print(f"[red]❌ Engine is not running (state: {engine['state']})[/red]")
969
974
  raise typer.Exit(1)
970
975
 
971
- console.print(
972
- f"Setting keep-awake for [cyan]{engine['name']}[/cyan] for {duration}..."
973
- )
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}…")
974
980
 
975
981
  # Use SSM to run the engine keep-alive command
976
982
  ssm = boto3.client("ssm", region_name="us-east-1")
@@ -979,7 +985,9 @@ def keep_awake(
979
985
  InstanceIds=[engine["instance_id"]],
980
986
  DocumentName="AWS-RunShellScript",
981
987
  Parameters={
982
- "commands": [f"engine keep-alive {duration}"],
988
+ "commands": [
989
+ ("/usr/local/bin/engine-coffee --cancel" if cancel else f"/usr/local/bin/engine-coffee {seconds_total}")
990
+ ],
983
991
  "executionTimeout": ["60"],
984
992
  },
985
993
  )
@@ -997,75 +1005,23 @@ def keep_awake(
997
1005
  break
998
1006
 
999
1007
  if result["Status"] == "Success":
1000
- 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]")
1001
1012
  console.print(
1002
1013
  "\n[dim]Note: Detached Docker containers (except dev containers) will also keep the engine awake.[/dim]"
1003
1014
  )
1004
1015
  console.print(
1005
- "[dim]Use keep-awake for nohup operations or other background tasks.[/dim]"
1006
- )
1007
- else:
1008
- console.print(
1009
- f"[red]❌ Failed to set keep-awake: {result.get('StatusDetails', 'Unknown error')}[/red]"
1010
- )
1011
-
1012
- except ClientError as e:
1013
- console.print(f"[red]❌ Failed to set keep-awake: {e}[/red]")
1014
-
1015
-
1016
- @engine_app.command("cancel-keep-awake")
1017
- def cancel_keep_awake(
1018
- name_or_id: str = typer.Argument(help="Engine name or instance ID"),
1019
- ):
1020
- """Cancel keep-awake and re-enable auto-shutdown."""
1021
- username = check_aws_sso()
1022
-
1023
- # Get all engines to resolve name
1024
- response = make_api_request("GET", "/engines")
1025
- if response.status_code != 200:
1026
- console.print("[red]❌ Failed to fetch engines[/red]")
1027
- raise typer.Exit(1)
1028
-
1029
- engines = response.json().get("engines", [])
1030
- engine = resolve_engine(name_or_id, engines)
1031
-
1032
- console.print(f"Cancelling keep-awake for [cyan]{engine['name']}[/cyan]...")
1033
-
1034
- # Use SSM to run the engine cancel command
1035
- ssm = boto3.client("ssm", region_name="us-east-1")
1036
- try:
1037
- response = ssm.send_command(
1038
- InstanceIds=[engine["instance_id"]],
1039
- DocumentName="AWS-RunShellScript",
1040
- Parameters={
1041
- "commands": ["engine cancel"],
1042
- "executionTimeout": ["60"],
1043
- },
1044
- )
1045
-
1046
- command_id = response["Command"]["CommandId"]
1047
-
1048
- # Wait for command to complete
1049
- for _ in range(10):
1050
- time.sleep(1)
1051
- result = ssm.get_command_invocation(
1052
- CommandId=command_id,
1053
- InstanceId=engine["instance_id"],
1054
- )
1055
- if result["Status"] in ["Success", "Failed"]:
1056
- break
1057
-
1058
- if result["Status"] == "Success":
1059
- console.print(
1060
- "[green]✓ Keep-awake cancelled, auto-shutdown re-enabled[/green]"
1016
+ "[dim]Use coffee for nohup operations or other background tasks.[/dim]"
1061
1017
  )
1062
1018
  else:
1063
1019
  console.print(
1064
- 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]"
1065
1021
  )
1066
1022
 
1067
1023
  except ClientError as e:
1068
- console.print(f"[red]❌ Failed to cancel keep-awake: {e}[/red]")
1024
+ console.print(f"[red]❌ Failed to manage coffee: {e}[/red]")
1069
1025
 
1070
1026
 
1071
1027
  @engine_app.command("resize")
@@ -1229,7 +1185,7 @@ def resize_engine(
1229
1185
  raise typer.Exit(1)
1230
1186
 
1231
1187
 
1232
- @engine_app.command("create-ami")
1188
+ @engine_app.command("gami")
1233
1189
  def create_ami(
1234
1190
  name_or_id: str = typer.Argument(
1235
1191
  help="Engine name or instance ID to create AMI from"
@@ -2007,7 +1963,7 @@ def resize_studio(
2007
1963
  # ================= Idle timeout command =================
2008
1964
 
2009
1965
 
2010
- @engine_app.command("idle-timeout")
1966
+ @engine_app.command("idle")
2011
1967
  def idle_timeout_cmd(
2012
1968
  name_or_id: str = typer.Argument(help="Engine name or instance ID"),
2013
1969
  set: Optional[str] = typer.Option(None, "--set", "-s", help="New timeout (e.g., 2h30m, 45m)")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: dayhoff-tools
3
- Version: 1.3.23
3
+ Version: 1.3.25
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=sSgz_4mBDfUazezpbcdW5S5sIsTzDWVSrJBozF-hutw,79904
6
+ dayhoff_tools/cli/engine_commands.py,sha256=XVg03q0MG4DpzMxep3VRbEWZqDU_LHRD3j_xKui4Ync,78722
7
7
  dayhoff_tools/cli/main.py,sha256=rgeEHD9lJ8SBCR34BTLb7gVInHUUdmEBNXAJnq5yEU4,4795
8
8
  dayhoff_tools/cli/swarm_commands.py,sha256=5EyKj8yietvT5lfoz8Zx0iQvVaNgc3SJX1z2zQR6o6M,5614
9
9
  dayhoff_tools/cli/utility_commands.py,sha256=qs8vH9TBFHsOPC3X8cU3qZigM3dDn-2Ytq4o_F2WubU,27874
@@ -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=8YbnQ--usrEgDQGfvpV4MrMji55A0rq2hZaOgFGh6ag,15896
30
- dayhoff_tools-1.3.23.dist-info/METADATA,sha256=VTbAe-npnV8ApVkgUpu1z2ALJRZ6psWeAMJsT253mO8,2825
31
- dayhoff_tools-1.3.23.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
32
- dayhoff_tools-1.3.23.dist-info/entry_points.txt,sha256=iAf4jteNqW3cJm6CO6czLxjW3vxYKsyGLZ8WGmxamSc,49
33
- dayhoff_tools-1.3.23.dist-info/RECORD,,
30
+ dayhoff_tools-1.3.25.dist-info/METADATA,sha256=-M4-C9Y0ICSbkfUiaIGTw_Voh9QnrIcYNGmklHYyZUU,2825
31
+ dayhoff_tools-1.3.25.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
32
+ dayhoff_tools-1.3.25.dist-info/entry_points.txt,sha256=iAf4jteNqW3cJm6CO6czLxjW3vxYKsyGLZ8WGmxamSc,49
33
+ dayhoff_tools-1.3.25.dist-info/RECORD,,