dayhoff-tools 1.6.9__tar.gz → 1.6.11__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.9 → dayhoff_tools-1.6.11}/PKG-INFO +1 -1
  2. {dayhoff_tools-1.6.9 → dayhoff_tools-1.6.11}/dayhoff_tools/cli/engine_commands.py +28 -18
  3. {dayhoff_tools-1.6.9 → dayhoff_tools-1.6.11}/pyproject.toml +1 -1
  4. {dayhoff_tools-1.6.9 → dayhoff_tools-1.6.11}/README.md +0 -0
  5. {dayhoff_tools-1.6.9 → dayhoff_tools-1.6.11}/dayhoff_tools/__init__.py +0 -0
  6. {dayhoff_tools-1.6.9 → dayhoff_tools-1.6.11}/dayhoff_tools/chemistry/standardizer.py +0 -0
  7. {dayhoff_tools-1.6.9 → dayhoff_tools-1.6.11}/dayhoff_tools/chemistry/utils.py +0 -0
  8. {dayhoff_tools-1.6.9 → dayhoff_tools-1.6.11}/dayhoff_tools/cli/__init__.py +0 -0
  9. {dayhoff_tools-1.6.9 → dayhoff_tools-1.6.11}/dayhoff_tools/cli/cloud_commands.py +0 -0
  10. {dayhoff_tools-1.6.9 → dayhoff_tools-1.6.11}/dayhoff_tools/cli/main.py +0 -0
  11. {dayhoff_tools-1.6.9 → dayhoff_tools-1.6.11}/dayhoff_tools/cli/swarm_commands.py +0 -0
  12. {dayhoff_tools-1.6.9 → dayhoff_tools-1.6.11}/dayhoff_tools/cli/utility_commands.py +0 -0
  13. {dayhoff_tools-1.6.9 → dayhoff_tools-1.6.11}/dayhoff_tools/deployment/base.py +0 -0
  14. {dayhoff_tools-1.6.9 → dayhoff_tools-1.6.11}/dayhoff_tools/deployment/deploy_aws.py +0 -0
  15. {dayhoff_tools-1.6.9 → dayhoff_tools-1.6.11}/dayhoff_tools/deployment/deploy_gcp.py +0 -0
  16. {dayhoff_tools-1.6.9 → dayhoff_tools-1.6.11}/dayhoff_tools/deployment/deploy_utils.py +0 -0
  17. {dayhoff_tools-1.6.9 → dayhoff_tools-1.6.11}/dayhoff_tools/deployment/job_runner.py +0 -0
  18. {dayhoff_tools-1.6.9 → dayhoff_tools-1.6.11}/dayhoff_tools/deployment/processors.py +0 -0
  19. {dayhoff_tools-1.6.9 → dayhoff_tools-1.6.11}/dayhoff_tools/deployment/swarm.py +0 -0
  20. {dayhoff_tools-1.6.9 → dayhoff_tools-1.6.11}/dayhoff_tools/embedders.py +0 -0
  21. {dayhoff_tools-1.6.9 → dayhoff_tools-1.6.11}/dayhoff_tools/fasta.py +0 -0
  22. {dayhoff_tools-1.6.9 → dayhoff_tools-1.6.11}/dayhoff_tools/file_ops.py +0 -0
  23. {dayhoff_tools-1.6.9 → dayhoff_tools-1.6.11}/dayhoff_tools/h5.py +0 -0
  24. {dayhoff_tools-1.6.9 → dayhoff_tools-1.6.11}/dayhoff_tools/intake/gcp.py +0 -0
  25. {dayhoff_tools-1.6.9 → dayhoff_tools-1.6.11}/dayhoff_tools/intake/gtdb.py +0 -0
  26. {dayhoff_tools-1.6.9 → dayhoff_tools-1.6.11}/dayhoff_tools/intake/kegg.py +0 -0
  27. {dayhoff_tools-1.6.9 → dayhoff_tools-1.6.11}/dayhoff_tools/intake/mmseqs.py +0 -0
  28. {dayhoff_tools-1.6.9 → dayhoff_tools-1.6.11}/dayhoff_tools/intake/structure.py +0 -0
  29. {dayhoff_tools-1.6.9 → dayhoff_tools-1.6.11}/dayhoff_tools/intake/uniprot.py +0 -0
  30. {dayhoff_tools-1.6.9 → dayhoff_tools-1.6.11}/dayhoff_tools/logs.py +0 -0
  31. {dayhoff_tools-1.6.9 → dayhoff_tools-1.6.11}/dayhoff_tools/sqlite.py +0 -0
  32. {dayhoff_tools-1.6.9 → dayhoff_tools-1.6.11}/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.9
3
+ Version: 1.6.11
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
@@ -1765,16 +1765,21 @@ def attach_studio(
1765
1765
 
1766
1766
  for attempt in range(max_attempts):
1767
1767
  # If the attach already completed in the previous iteration (but we
1768
- # didn't notice because the operation table wasnt updated yet),
1768
+ # didn't notice because the operation table wasn't updated yet),
1769
1769
  # bail out early.
1770
1770
  if _is_studio_attached(studio["studio_id"], engine["instance_id"]):
1771
+ console.print("[dim]DEBUG: Studio already attached (detected by _is_studio_attached)[/dim]")
1771
1772
  success = True
1772
1773
  break
1774
+
1775
+ console.print(f"[dim]DEBUG: Attempt {attempt + 1}/{max_attempts}[/dim]")
1773
1776
  success, error_msg = _attempt_studio_attach(
1774
1777
  studio, engine, target_user, public_key
1775
1778
  )
1779
+ console.print(f"[dim]DEBUG: Attempt result: success={success}, error_msg={error_msg}[/dim]")
1776
1780
 
1777
1781
  if success:
1782
+ console.print("[dim]DEBUG: Success! Breaking out of retry loop[/dim]")
1778
1783
  break # success!
1779
1784
 
1780
1785
  if error_msg:
@@ -1846,8 +1851,17 @@ def _attempt_studio_attach(studio, engine, target_user, public_key):
1846
1851
  },
1847
1852
  )
1848
1853
 
1854
+ # DEBUG: Log what we're getting back
1855
+ console.print(f"[dim]DEBUG: Attach response: {response.status_code}[/dim]")
1856
+ if response.status_code not in (200, 202):
1857
+ try:
1858
+ console.print(f"[dim]DEBUG: Error: {response.json().get('error', 'No error field')}[/dim]")
1859
+ except:
1860
+ console.print(f"[dim]DEBUG: Could not parse error response[/dim]")
1861
+
1849
1862
  # Fast-path success
1850
1863
  if response.status_code == 200:
1864
+ console.print("[dim]DEBUG: Got 200 - immediate success[/dim]")
1851
1865
  return True, None
1852
1866
 
1853
1867
  # Asynchronous path – API returned 202 Accepted and operation tracking ID
@@ -1855,40 +1869,38 @@ def _attempt_studio_attach(studio, engine, target_user, public_key):
1855
1869
  op_id = response.json().get("operation_id")
1856
1870
  if not op_id:
1857
1871
  return False, "Async operation started but no operation_id returned"
1872
+ console.print(f"[dim]DEBUG: Got 202 - polling operation {op_id}[/dim]")
1858
1873
  poll_ok, poll_err = _poll_operation(op_id)
1874
+ console.print(f"[dim]DEBUG: Poll result: ok={poll_ok}, err={poll_err}[/dim]")
1859
1875
  if poll_ok:
1860
1876
  return True, None
1861
1877
  return False, poll_err
1862
1878
 
1863
1879
  # --- determine if we should retry ---
1864
1880
  recoverable = False
1881
+ error_text = response.json().get("error", "Unknown error")
1882
+ err_msg = error_text.lower()
1883
+
1884
+ # Check for "Studio is not available (status: in-use)" which means it's already attached
1885
+ if response.status_code == 400 and "not available" in err_msg and "in-use" in err_msg:
1886
+ # Studio is already attached somewhere - check if it's to THIS engine
1887
+ if _is_studio_attached(studio["studio_id"], engine["instance_id"]):
1888
+ return True, None # It's attached to our target engine - success!
1889
+ else:
1890
+ return False, error_text # It's attached elsewhere - fatal error
1891
+
1865
1892
  if response.status_code in (409, 503):
1866
- # Special-case: 409 because studio is already in-use. If it's attached to
1867
- # *this* engine we can safely treat it as success.
1868
- if response.status_code == 409:
1869
- try:
1870
- err_text = response.json().get("error", "").lower()
1871
- except Exception:
1872
- err_text = ""
1873
- # Fast path – avoid another API call when we know why we got 409.
1874
- if "in-use" in err_text or "already attached" in err_text:
1875
- if _is_studio_attached(studio["studio_id"], engine["instance_id"]):
1876
- return True, None
1877
1893
  recoverable = True
1878
1894
  else:
1879
- err_msg = response.json().get("error", "").lower()
1880
1895
  RECOVERABLE_PATTERNS = [
1881
1896
  "not ready",
1882
1897
  "still starting",
1883
1898
  "initializing",
1884
1899
  "failed to mount",
1885
1900
  "device busy",
1886
- "not available",
1887
1901
  "pending", # VM state pending
1888
1902
  ]
1889
1903
  FATAL_PATTERNS = [
1890
- "in-use",
1891
- "already attached",
1892
1904
  "permission",
1893
1905
  ]
1894
1906
  if any(p in err_msg for p in FATAL_PATTERNS):
@@ -1896,8 +1908,6 @@ def _attempt_studio_attach(studio, engine, target_user, public_key):
1896
1908
  elif any(p in err_msg for p in RECOVERABLE_PATTERNS):
1897
1909
  recoverable = True
1898
1910
 
1899
- error_text = response.json().get("error", "Unknown error")
1900
-
1901
1911
  if not recoverable:
1902
1912
  # fatal – abort immediately
1903
1913
  return False, error_text
@@ -5,7 +5,7 @@ build-backend = "poetry.core.masonry.api"
5
5
 
6
6
  [project]
7
7
  name = "dayhoff-tools"
8
- version = "1.6.9"
8
+ version = "1.6.11"
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