dayhoff-tools 1.6.9__py3-none-any.whl → 1.6.11__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.
- dayhoff_tools/cli/engine_commands.py +28 -18
- {dayhoff_tools-1.6.9.dist-info → dayhoff_tools-1.6.11.dist-info}/METADATA +1 -1
- {dayhoff_tools-1.6.9.dist-info → dayhoff_tools-1.6.11.dist-info}/RECORD +5 -5
- {dayhoff_tools-1.6.9.dist-info → dayhoff_tools-1.6.11.dist-info}/WHEEL +0 -0
- {dayhoff_tools-1.6.9.dist-info → dayhoff_tools-1.6.11.dist-info}/entry_points.txt +0 -0
@@ -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 wasn
|
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
|
@@ -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=
|
6
|
+
dayhoff_tools/cli/engine_commands.py,sha256=ssaYgeQDa3vWbPBlHxZdDPtJpfArZZ7POb6eJBKHong,97240
|
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.6.
|
31
|
-
dayhoff_tools-1.6.
|
32
|
-
dayhoff_tools-1.6.
|
33
|
-
dayhoff_tools-1.6.
|
30
|
+
dayhoff_tools-1.6.11.dist-info/METADATA,sha256=puTF_Rt1kbAL-R8hz0BpxBjNacbGcJlACatfMSsSwgU,2915
|
31
|
+
dayhoff_tools-1.6.11.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
32
|
+
dayhoff_tools-1.6.11.dist-info/entry_points.txt,sha256=iAf4jteNqW3cJm6CO6czLxjW3vxYKsyGLZ8WGmxamSc,49
|
33
|
+
dayhoff_tools-1.6.11.dist-info/RECORD,,
|
File without changes
|
File without changes
|