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.
Files changed (32) hide show
  1. {podstack-1.2.1 → podstack-1.2.2}/PKG-INFO +1 -1
  2. {podstack-1.2.1 → podstack-1.2.2}/podstack/__init__.py +1 -1
  3. {podstack-1.2.1 → podstack-1.2.2}/podstack/gpu_runner.py +16 -4
  4. {podstack-1.2.1 → podstack-1.2.2}/podstack.egg-info/PKG-INFO +1 -1
  5. {podstack-1.2.1 → podstack-1.2.2}/pyproject.toml +1 -1
  6. {podstack-1.2.1 → podstack-1.2.2}/LICENSE +0 -0
  7. {podstack-1.2.1 → podstack-1.2.2}/README.md +0 -0
  8. {podstack-1.2.1 → podstack-1.2.2}/podstack/annotations.py +0 -0
  9. {podstack-1.2.1 → podstack-1.2.2}/podstack/client.py +0 -0
  10. {podstack-1.2.1 → podstack-1.2.2}/podstack/exceptions.py +0 -0
  11. {podstack-1.2.1 → podstack-1.2.2}/podstack/execution.py +0 -0
  12. {podstack-1.2.1 → podstack-1.2.2}/podstack/models.py +0 -0
  13. {podstack-1.2.1 → podstack-1.2.2}/podstack/notebook.py +0 -0
  14. {podstack-1.2.1 → podstack-1.2.2}/podstack/registry/__init__.py +0 -0
  15. {podstack-1.2.1 → podstack-1.2.2}/podstack/registry/client.py +0 -0
  16. {podstack-1.2.1 → podstack-1.2.2}/podstack/registry/exceptions.py +0 -0
  17. {podstack-1.2.1 → podstack-1.2.2}/podstack/registry/experiment.py +0 -0
  18. {podstack-1.2.1 → podstack-1.2.2}/podstack/registry/model.py +0 -0
  19. {podstack-1.2.1 → podstack-1.2.2}/podstack/registry/model_utils.py +0 -0
  20. {podstack-1.2.1 → podstack-1.2.2}/podstack.egg-info/SOURCES.txt +0 -0
  21. {podstack-1.2.1 → podstack-1.2.2}/podstack.egg-info/dependency_links.txt +0 -0
  22. {podstack-1.2.1 → podstack-1.2.2}/podstack.egg-info/requires.txt +0 -0
  23. {podstack-1.2.1 → podstack-1.2.2}/podstack.egg-info/top_level.txt +0 -0
  24. {podstack-1.2.1 → podstack-1.2.2}/podstack_gpu/__init__.py +0 -0
  25. {podstack-1.2.1 → podstack-1.2.2}/podstack_gpu/app.py +0 -0
  26. {podstack-1.2.1 → podstack-1.2.2}/podstack_gpu/exceptions.py +0 -0
  27. {podstack-1.2.1 → podstack-1.2.2}/podstack_gpu/image.py +0 -0
  28. {podstack-1.2.1 → podstack-1.2.2}/podstack_gpu/runner.py +0 -0
  29. {podstack-1.2.1 → podstack-1.2.2}/podstack_gpu/secret.py +0 -0
  30. {podstack-1.2.1 → podstack-1.2.2}/podstack_gpu/utils.py +0 -0
  31. {podstack-1.2.1 → podstack-1.2.2}/podstack_gpu/volume.py +0 -0
  32. {podstack-1.2.1 → podstack-1.2.2}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: podstack
3
- Version: 1.2.1
3
+ Version: 1.2.2
4
4
  Summary: Official Python SDK for Podstack GPU Notebook Platform
5
5
  Author-email: Podstack <support@podstack.ai>
6
6
  License-Expression: MIT
@@ -54,7 +54,7 @@ Decorators:
54
54
  ...
55
55
  """
56
56
 
57
- __version__ = "1.2.1"
57
+ __version__ = "1.2.2"
58
58
 
59
59
  from .client import Client
60
60
  from .notebook import Notebook, NotebookStatus
@@ -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.0.3"
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}")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: podstack
3
- Version: 1.2.1
3
+ Version: 1.2.2
4
4
  Summary: Official Python SDK for Podstack GPU Notebook Platform
5
5
  Author-email: Podstack <support@podstack.ai>
6
6
  License-Expression: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "podstack"
7
- version = "1.2.1"
7
+ version = "1.2.2"
8
8
  description = "Official Python SDK for Podstack GPU Notebook Platform"
9
9
  readme = "README.md"
10
10
  license = "MIT"
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