dayhoff-tools 1.6.12__tar.gz → 1.6.14__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.6.12 → dayhoff_tools-1.6.14}/PKG-INFO +1 -1
  2. {dayhoff_tools-1.6.12 → dayhoff_tools-1.6.14}/dayhoff_tools/cli/engine_commands.py +46 -38
  3. {dayhoff_tools-1.6.12 → dayhoff_tools-1.6.14}/pyproject.toml +1 -1
  4. {dayhoff_tools-1.6.12 → dayhoff_tools-1.6.14}/README.md +0 -0
  5. {dayhoff_tools-1.6.12 → dayhoff_tools-1.6.14}/dayhoff_tools/__init__.py +0 -0
  6. {dayhoff_tools-1.6.12 → dayhoff_tools-1.6.14}/dayhoff_tools/chemistry/standardizer.py +0 -0
  7. {dayhoff_tools-1.6.12 → dayhoff_tools-1.6.14}/dayhoff_tools/chemistry/utils.py +0 -0
  8. {dayhoff_tools-1.6.12 → dayhoff_tools-1.6.14}/dayhoff_tools/cli/__init__.py +0 -0
  9. {dayhoff_tools-1.6.12 → dayhoff_tools-1.6.14}/dayhoff_tools/cli/cloud_commands.py +0 -0
  10. {dayhoff_tools-1.6.12 → dayhoff_tools-1.6.14}/dayhoff_tools/cli/main.py +0 -0
  11. {dayhoff_tools-1.6.12 → dayhoff_tools-1.6.14}/dayhoff_tools/cli/swarm_commands.py +0 -0
  12. {dayhoff_tools-1.6.12 → dayhoff_tools-1.6.14}/dayhoff_tools/cli/utility_commands.py +0 -0
  13. {dayhoff_tools-1.6.12 → dayhoff_tools-1.6.14}/dayhoff_tools/deployment/base.py +0 -0
  14. {dayhoff_tools-1.6.12 → dayhoff_tools-1.6.14}/dayhoff_tools/deployment/deploy_aws.py +0 -0
  15. {dayhoff_tools-1.6.12 → dayhoff_tools-1.6.14}/dayhoff_tools/deployment/deploy_gcp.py +0 -0
  16. {dayhoff_tools-1.6.12 → dayhoff_tools-1.6.14}/dayhoff_tools/deployment/deploy_utils.py +0 -0
  17. {dayhoff_tools-1.6.12 → dayhoff_tools-1.6.14}/dayhoff_tools/deployment/job_runner.py +0 -0
  18. {dayhoff_tools-1.6.12 → dayhoff_tools-1.6.14}/dayhoff_tools/deployment/processors.py +0 -0
  19. {dayhoff_tools-1.6.12 → dayhoff_tools-1.6.14}/dayhoff_tools/deployment/swarm.py +0 -0
  20. {dayhoff_tools-1.6.12 → dayhoff_tools-1.6.14}/dayhoff_tools/embedders.py +0 -0
  21. {dayhoff_tools-1.6.12 → dayhoff_tools-1.6.14}/dayhoff_tools/fasta.py +0 -0
  22. {dayhoff_tools-1.6.12 → dayhoff_tools-1.6.14}/dayhoff_tools/file_ops.py +0 -0
  23. {dayhoff_tools-1.6.12 → dayhoff_tools-1.6.14}/dayhoff_tools/h5.py +0 -0
  24. {dayhoff_tools-1.6.12 → dayhoff_tools-1.6.14}/dayhoff_tools/intake/gcp.py +0 -0
  25. {dayhoff_tools-1.6.12 → dayhoff_tools-1.6.14}/dayhoff_tools/intake/gtdb.py +0 -0
  26. {dayhoff_tools-1.6.12 → dayhoff_tools-1.6.14}/dayhoff_tools/intake/kegg.py +0 -0
  27. {dayhoff_tools-1.6.12 → dayhoff_tools-1.6.14}/dayhoff_tools/intake/mmseqs.py +0 -0
  28. {dayhoff_tools-1.6.12 → dayhoff_tools-1.6.14}/dayhoff_tools/intake/structure.py +0 -0
  29. {dayhoff_tools-1.6.12 → dayhoff_tools-1.6.14}/dayhoff_tools/intake/uniprot.py +0 -0
  30. {dayhoff_tools-1.6.12 → dayhoff_tools-1.6.14}/dayhoff_tools/logs.py +0 -0
  31. {dayhoff_tools-1.6.12 → dayhoff_tools-1.6.14}/dayhoff_tools/sqlite.py +0 -0
  32. {dayhoff_tools-1.6.12 → dayhoff_tools-1.6.14}/dayhoff_tools/warehouse.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: dayhoff-tools
3
- Version: 1.6.12
3
+ Version: 1.6.14
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
@@ -1610,6 +1610,36 @@ def studio_status(
1610
1610
  console.print(panel)
1611
1611
 
1612
1612
 
1613
+ def _is_studio_attached(target_studio_id: str, target_vm_id: str) -> bool:
1614
+ """Return True when the given studio already shows as attached to the VM.
1615
+
1616
+ Using this extra check lets us stop the outer retry loop as soon as the
1617
+ asynchronous attach operation actually finishes, even in the unlikely
1618
+ event that the operation-tracking DynamoDB record is not yet updated.
1619
+ """
1620
+ # First try the per-studio endpoint – fastest.
1621
+ resp = make_api_request("GET", f"/studios/{target_studio_id}")
1622
+ if resp.status_code == 200:
1623
+ data = resp.json()
1624
+ if (
1625
+ data.get("status") == "in-use"
1626
+ and data.get("attached_vm_id") == target_vm_id
1627
+ ):
1628
+ return True
1629
+ # Fallback: list + filter (covers edge-cases where the direct endpoint
1630
+ # is slower to update IAM/APIGW mapping than the list endpoint).
1631
+ list_resp = make_api_request("GET", "/studios")
1632
+ if list_resp.status_code == 200:
1633
+ for stu in list_resp.json().get("studios", []):
1634
+ if (
1635
+ stu.get("studio_id") == target_studio_id
1636
+ and stu.get("status") == "in-use"
1637
+ and stu.get("attached_vm_id") == target_vm_id
1638
+ ):
1639
+ return True
1640
+ return False
1641
+
1642
+
1613
1643
  @studio_app.command("attach")
1614
1644
  def attach_studio(
1615
1645
  engine_name_or_id: str = typer.Argument(help="Engine name or instance ID"),
@@ -1710,36 +1740,6 @@ def attach_studio(
1710
1740
 
1711
1741
  console.print(f"Attaching studio to engine [cyan]{engine['name']}[/cyan]...")
1712
1742
 
1713
- # Helper --------------------------------------------------------------
1714
- def _is_studio_attached(target_studio_id: str, target_vm_id: str) -> bool:
1715
- """Return True when the given studio already shows as attached to the VM.
1716
-
1717
- Using this extra check lets us stop the outer retry loop as soon as the
1718
- asynchronous attach operation actually finishes, even in the unlikely
1719
- event that the operation-tracking DynamoDB record is not yet updated.
1720
- """
1721
- # First try the per-studio endpoint – fastest.
1722
- resp = make_api_request("GET", f"/studios/{target_studio_id}")
1723
- if resp.status_code == 200:
1724
- data = resp.json()
1725
- if (
1726
- data.get("status") == "in-use"
1727
- and data.get("attached_vm_id") == target_vm_id
1728
- ):
1729
- return True
1730
- # Fallback: list + filter (covers edge-cases where the direct endpoint
1731
- # is slower to update IAM/APIGW mapping than the list endpoint).
1732
- list_resp = make_api_request("GET", "/studios")
1733
- if list_resp.status_code == 200:
1734
- for stu in list_resp.json().get("studios", []):
1735
- if (
1736
- stu.get("studio_id") == target_studio_id
1737
- and stu.get("status") == "in-use"
1738
- and stu.get("attached_vm_id") == target_vm_id
1739
- ):
1740
- return True
1741
- return False
1742
-
1743
1743
  # Determine retry strategy based on whether we just started the engine
1744
1744
  if engine_started_now:
1745
1745
  max_attempts = 40 # About 7 minutes total with exponential backoff
@@ -1867,14 +1867,22 @@ def _attempt_studio_attach(studio, engine, target_user, public_key):
1867
1867
  # Asynchronous path – API returned 202 Accepted and operation tracking ID
1868
1868
  if response.status_code == 202:
1869
1869
  op_id = response.json().get("operation_id")
1870
- if not op_id:
1871
- return False, "Async operation started but no operation_id returned"
1872
- console.print(f"[dim]DEBUG: Got 202 - polling operation {op_id}[/dim]")
1873
- poll_ok, poll_err = _poll_operation(op_id)
1874
- console.print(f"[dim]DEBUG: Poll result: ok={poll_ok}, err={poll_err}[/dim]")
1875
- if poll_ok:
1876
- return True, None
1877
- return False, poll_err
1870
+ console.print(f"[dim]DEBUG: Got 202 - operation {op_id} started[/dim]")
1871
+
1872
+ # Instead of polling the operation status (which seems broken),
1873
+ # just wait a bit and check if the studio is actually attached
1874
+ # This is what dh studio status does and it works reliably
1875
+ time.sleep(5) # Give the async operation a moment to start
1876
+
1877
+ # Now check periodically if the studio is attached
1878
+ for check in range(20): # Check for up to 60 seconds
1879
+ if _is_studio_attached(studio["studio_id"], engine["instance_id"]):
1880
+ console.print("[dim]DEBUG: Studio attachment detected via status check[/dim]")
1881
+ return True, None
1882
+ time.sleep(3)
1883
+
1884
+ # If we get here, attachment didn't complete in reasonable time
1885
+ return False, None # Return None to trigger retry
1878
1886
 
1879
1887
  # --- determine if we should retry ---
1880
1888
  recoverable = False
@@ -5,7 +5,7 @@ build-backend = "poetry.core.masonry.api"
5
5
 
6
6
  [project]
7
7
  name = "dayhoff-tools"
8
- version = "1.6.12"
8
+ version = "1.6.14"
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