podstack 1.3.0__tar.gz → 1.3.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.3.0 → podstack-1.3.2}/PKG-INFO +1 -1
  2. {podstack-1.3.0 → podstack-1.3.2}/podstack/__init__.py +3 -1
  3. {podstack-1.3.0 → podstack-1.3.2}/podstack/gpu_runner.py +53 -9
  4. {podstack-1.3.0 → podstack-1.3.2}/podstack.egg-info/PKG-INFO +1 -1
  5. {podstack-1.3.0 → podstack-1.3.2}/pyproject.toml +1 -1
  6. {podstack-1.3.0 → podstack-1.3.2}/LICENSE +0 -0
  7. {podstack-1.3.0 → podstack-1.3.2}/README.md +0 -0
  8. {podstack-1.3.0 → podstack-1.3.2}/podstack/annotations.py +0 -0
  9. {podstack-1.3.0 → podstack-1.3.2}/podstack/client.py +0 -0
  10. {podstack-1.3.0 → podstack-1.3.2}/podstack/exceptions.py +0 -0
  11. {podstack-1.3.0 → podstack-1.3.2}/podstack/execution.py +0 -0
  12. {podstack-1.3.0 → podstack-1.3.2}/podstack/models.py +0 -0
  13. {podstack-1.3.0 → podstack-1.3.2}/podstack/notebook.py +0 -0
  14. {podstack-1.3.0 → podstack-1.3.2}/podstack/registry/__init__.py +0 -0
  15. {podstack-1.3.0 → podstack-1.3.2}/podstack/registry/client.py +0 -0
  16. {podstack-1.3.0 → podstack-1.3.2}/podstack/registry/exceptions.py +0 -0
  17. {podstack-1.3.0 → podstack-1.3.2}/podstack/registry/experiment.py +0 -0
  18. {podstack-1.3.0 → podstack-1.3.2}/podstack/registry/model.py +0 -0
  19. {podstack-1.3.0 → podstack-1.3.2}/podstack/registry/model_utils.py +0 -0
  20. {podstack-1.3.0 → podstack-1.3.2}/podstack.egg-info/SOURCES.txt +0 -0
  21. {podstack-1.3.0 → podstack-1.3.2}/podstack.egg-info/dependency_links.txt +0 -0
  22. {podstack-1.3.0 → podstack-1.3.2}/podstack.egg-info/requires.txt +0 -0
  23. {podstack-1.3.0 → podstack-1.3.2}/podstack.egg-info/top_level.txt +0 -0
  24. {podstack-1.3.0 → podstack-1.3.2}/podstack_gpu/__init__.py +0 -0
  25. {podstack-1.3.0 → podstack-1.3.2}/podstack_gpu/app.py +0 -0
  26. {podstack-1.3.0 → podstack-1.3.2}/podstack_gpu/exceptions.py +0 -0
  27. {podstack-1.3.0 → podstack-1.3.2}/podstack_gpu/image.py +0 -0
  28. {podstack-1.3.0 → podstack-1.3.2}/podstack_gpu/runner.py +0 -0
  29. {podstack-1.3.0 → podstack-1.3.2}/podstack_gpu/secret.py +0 -0
  30. {podstack-1.3.0 → podstack-1.3.2}/podstack_gpu/utils.py +0 -0
  31. {podstack-1.3.0 → podstack-1.3.2}/podstack_gpu/volume.py +0 -0
  32. {podstack-1.3.0 → podstack-1.3.2}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: podstack
3
- Version: 1.3.0
3
+ Version: 1.3.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.3.0"
57
+ __version__ = "1.3.2"
58
58
 
59
59
  from .client import Client
60
60
  from .notebook import Notebook, NotebookStatus
@@ -83,6 +83,7 @@ from . import gpu_runner
83
83
  from .gpu_runner import (
84
84
  GPURunner,
85
85
  GPUExecutionResult,
86
+ RunnerList,
86
87
  run as run_on_gpu,
87
88
  list_runners,
88
89
  )
@@ -209,6 +210,7 @@ __all__ = [
209
210
  "gpu_runner",
210
211
  "GPURunner",
211
212
  "GPUExecutionResult",
213
+ "RunnerList",
212
214
  "run_on_gpu",
213
215
  "list_runners",
214
216
  # Annotations
@@ -35,6 +35,33 @@ def is_jupyter() -> bool:
35
35
  return False
36
36
 
37
37
 
38
+ class RunnerList(list):
39
+ """A list of runners with a .show() method for tabular display."""
40
+
41
+ def show(self):
42
+ """Print runners in a formatted table with S.NO."""
43
+ if not self:
44
+ print("No runners available.")
45
+ return
46
+
47
+ # Column widths
48
+ no_w = 5
49
+ name_w = 45
50
+ type_w = 6
51
+ desc_w = 50
52
+
53
+ header = f"{'S.NO':<{no_w}} {'Name':<{name_w}} {'Type':<{type_w}} {'Description'}"
54
+ print(header)
55
+ print("-" * (no_w + name_w + type_w + desc_w + 3))
56
+ for i, r in enumerate(self, 1):
57
+ name = r.get("name", "")
58
+ rtype = r.get("type", "")
59
+ desc = r.get("description", "")
60
+ if len(desc) > desc_w:
61
+ desc = desc[:desc_w - 3] + "..."
62
+ print(f"{i:<{no_w}} {name:<{name_w}} {rtype:<{type_w}} {desc}")
63
+
64
+
38
65
  class OutputStreamer:
39
66
  """Handles real-time output streaming from GPU executions."""
40
67
 
@@ -965,14 +992,32 @@ _stream_install(
965
992
  except:
966
993
  return {"status": "cancelled"}
967
994
 
968
- def list_runners(self) -> list:
995
+ def _get_platform_url(self) -> str:
996
+ """Derive the platform service URL from the notebook service URL."""
997
+ if os.environ.get("PODSTACK_PLATFORM_URL"):
998
+ return os.environ.get("PODSTACK_PLATFORM_URL")
999
+ # External: cloud.podstack.ai/notebooks -> cloud.podstack.ai/platform
1000
+ if "/notebooks" in self.api_url:
1001
+ return self.api_url.replace("/notebooks", "/platform")
1002
+ # Internal K8s: notebook service URL -> platform service URL
1003
+ if "notebook" in self.api_url and ".svc.cluster.local" in self.api_url:
1004
+ return self.api_url.replace("notebook", "platform").replace(":8084", ":8081")
1005
+ # Fallback: use the same base URL
1006
+ return self.api_url
1007
+
1008
+ def list_runners(self) -> RunnerList:
969
1009
  """
970
1010
  List available GPU/CPU runners.
971
1011
 
972
1012
  Returns:
973
- List of runner dictionaries with name, type, description, image, libraries, scenarios.
1013
+ RunnerList of runner dictionaries. Call .show() for tabular display.
1014
+
1015
+ Example:
1016
+ podstack.list_runners().show() # Print table with S.NO
1017
+ runners = podstack.list_runners() # Just fetch list
974
1018
  """
975
- url = f"{self.api_url}/api/v1/runners"
1019
+ platform_url = self._get_platform_url()
1020
+ url = f"{platform_url}/api/v1/runners"
976
1021
 
977
1022
  with httpx.Client(timeout=self.timeout) as client:
978
1023
  try:
@@ -990,7 +1035,7 @@ _stream_install(
990
1035
  raise RuntimeError(f"Failed to list runners: {error_msg}")
991
1036
 
992
1037
  try:
993
- return response.json()
1038
+ return RunnerList(response.json())
994
1039
  except Exception:
995
1040
  raise RuntimeError(f"Invalid JSON response: {response.text[:200]}")
996
1041
 
@@ -1167,17 +1212,16 @@ def run(
1167
1212
  )
1168
1213
 
1169
1214
 
1170
- def list_runners() -> list:
1215
+ def list_runners() -> RunnerList:
1171
1216
  """
1172
1217
  List available GPU/CPU runners.
1173
1218
 
1174
1219
  Returns:
1175
- List of runner dictionaries with name, type, description, image, libraries, scenarios.
1220
+ RunnerList of runner dicts. Call .show() for tabular display.
1176
1221
 
1177
1222
  Example:
1178
- runners = podstack.gpu_runner.list_runners()
1179
- for r in runners:
1180
- print(f"{r['name']} ({r['type']}): {r['description']}")
1223
+ podstack.list_runners().show() # Print table with S.NO
1224
+ runners = podstack.list_runners() # Just fetch list
1181
1225
  """
1182
1226
  return get_runner().list_runners()
1183
1227
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: podstack
3
- Version: 1.3.0
3
+ Version: 1.3.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.3.0"
7
+ version = "1.3.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