podstack 1.2.1__tar.gz → 1.2.2__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.
- {podstack-1.2.1 → podstack-1.2.2}/PKG-INFO +1 -1
- {podstack-1.2.1 → podstack-1.2.2}/podstack/__init__.py +1 -1
- {podstack-1.2.1 → podstack-1.2.2}/podstack/gpu_runner.py +16 -4
- {podstack-1.2.1 → podstack-1.2.2}/podstack.egg-info/PKG-INFO +1 -1
- {podstack-1.2.1 → podstack-1.2.2}/pyproject.toml +1 -1
- {podstack-1.2.1 → podstack-1.2.2}/LICENSE +0 -0
- {podstack-1.2.1 → podstack-1.2.2}/README.md +0 -0
- {podstack-1.2.1 → podstack-1.2.2}/podstack/annotations.py +0 -0
- {podstack-1.2.1 → podstack-1.2.2}/podstack/client.py +0 -0
- {podstack-1.2.1 → podstack-1.2.2}/podstack/exceptions.py +0 -0
- {podstack-1.2.1 → podstack-1.2.2}/podstack/execution.py +0 -0
- {podstack-1.2.1 → podstack-1.2.2}/podstack/models.py +0 -0
- {podstack-1.2.1 → podstack-1.2.2}/podstack/notebook.py +0 -0
- {podstack-1.2.1 → podstack-1.2.2}/podstack/registry/__init__.py +0 -0
- {podstack-1.2.1 → podstack-1.2.2}/podstack/registry/client.py +0 -0
- {podstack-1.2.1 → podstack-1.2.2}/podstack/registry/exceptions.py +0 -0
- {podstack-1.2.1 → podstack-1.2.2}/podstack/registry/experiment.py +0 -0
- {podstack-1.2.1 → podstack-1.2.2}/podstack/registry/model.py +0 -0
- {podstack-1.2.1 → podstack-1.2.2}/podstack/registry/model_utils.py +0 -0
- {podstack-1.2.1 → podstack-1.2.2}/podstack.egg-info/SOURCES.txt +0 -0
- {podstack-1.2.1 → podstack-1.2.2}/podstack.egg-info/dependency_links.txt +0 -0
- {podstack-1.2.1 → podstack-1.2.2}/podstack.egg-info/requires.txt +0 -0
- {podstack-1.2.1 → podstack-1.2.2}/podstack.egg-info/top_level.txt +0 -0
- {podstack-1.2.1 → podstack-1.2.2}/podstack_gpu/__init__.py +0 -0
- {podstack-1.2.1 → podstack-1.2.2}/podstack_gpu/app.py +0 -0
- {podstack-1.2.1 → podstack-1.2.2}/podstack_gpu/exceptions.py +0 -0
- {podstack-1.2.1 → podstack-1.2.2}/podstack_gpu/image.py +0 -0
- {podstack-1.2.1 → podstack-1.2.2}/podstack_gpu/runner.py +0 -0
- {podstack-1.2.1 → podstack-1.2.2}/podstack_gpu/secret.py +0 -0
- {podstack-1.2.1 → podstack-1.2.2}/podstack_gpu/utils.py +0 -0
- {podstack-1.2.1 → podstack-1.2.2}/podstack_gpu/volume.py +0 -0
- {podstack-1.2.1 → podstack-1.2.2}/setup.cfg +0 -0
|
@@ -38,10 +38,11 @@ def is_jupyter() -> bool:
|
|
|
38
38
|
class OutputStreamer:
|
|
39
39
|
"""Handles real-time output streaming from GPU executions."""
|
|
40
40
|
|
|
41
|
-
def __init__(self, execution_id: str, api_url: str, headers: Dict[str, str], timeout: float = 30.0):
|
|
41
|
+
def __init__(self, execution_id: str, api_url: str, headers: Dict[str, str], timeout: float = 30.0, api_key: str = None):
|
|
42
42
|
self.execution_id = execution_id
|
|
43
43
|
self.api_url = api_url
|
|
44
44
|
self.headers = headers
|
|
45
|
+
self.api_key = api_key
|
|
45
46
|
self.timeout = timeout
|
|
46
47
|
self._output_buffer: List[str] = []
|
|
47
48
|
self._status = "running"
|
|
@@ -56,10 +57,14 @@ class OutputStreamer:
|
|
|
56
57
|
Dict with event data (type, content, timestamp, etc.)
|
|
57
58
|
"""
|
|
58
59
|
url = f"{self.api_url}/api/v1/executions/{self.execution_id}/stream"
|
|
60
|
+
# Pass token as query param for SSE — proxies often strip Authorization header on streaming connections
|
|
61
|
+
params = {}
|
|
62
|
+
if self.api_key:
|
|
63
|
+
params["token"] = self.api_key
|
|
59
64
|
|
|
60
65
|
try:
|
|
61
66
|
with httpx.Client(timeout=httpx.Timeout(self.timeout, read=None)) as client:
|
|
62
|
-
with client.stream("GET", url, headers=self.headers) as response:
|
|
67
|
+
with client.stream("GET", url, headers=self.headers, params=params) as response:
|
|
63
68
|
if response.status_code != 200:
|
|
64
69
|
raise RuntimeError(f"Failed to connect to stream: HTTP {response.status_code}")
|
|
65
70
|
|
|
@@ -249,7 +254,7 @@ class GPURunner:
|
|
|
249
254
|
return {
|
|
250
255
|
"Authorization": f"Bearer {self.api_key}",
|
|
251
256
|
"Content-Type": "application/json",
|
|
252
|
-
"User-Agent": "podstack-python-sdk/1.
|
|
257
|
+
"User-Agent": "podstack-python-sdk/1.2.2"
|
|
253
258
|
}
|
|
254
259
|
|
|
255
260
|
def _build_annotation(
|
|
@@ -607,7 +612,8 @@ _stream_install(
|
|
|
607
612
|
execution_id=execution_id,
|
|
608
613
|
api_url=self.api_url,
|
|
609
614
|
headers=self._get_headers(),
|
|
610
|
-
timeout=self.timeout
|
|
615
|
+
timeout=self.timeout,
|
|
616
|
+
api_key=self.api_key
|
|
611
617
|
)
|
|
612
618
|
yield from streamer.stream(show_output=show_output)
|
|
613
619
|
|
|
@@ -750,6 +756,12 @@ _stream_install(
|
|
|
750
756
|
final_event = event
|
|
751
757
|
break
|
|
752
758
|
|
|
759
|
+
except RuntimeError as e:
|
|
760
|
+
if "HTTP 401" in str(e):
|
|
761
|
+
# Auth failed on stream — fall back to polling
|
|
762
|
+
print(f"\n[Podstack] Streaming auth failed, falling back to polling...")
|
|
763
|
+
return self._run_with_polling(execution_id, gpu, count, timeout, 2.0, max_retries, 300, cancel_on_timeout)
|
|
764
|
+
raise
|
|
753
765
|
except (ConnectionError, httpx.ConnectError) as e:
|
|
754
766
|
# Try to recover and get the result
|
|
755
767
|
logger.warning(f"Stream connection lost: {e}")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|