podstack 1.2.0__tar.gz → 1.2.1__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 (35) hide show
  1. podstack-1.2.1/PKG-INFO +467 -0
  2. podstack-1.2.1/README.md +415 -0
  3. {podstack-1.2.0 → podstack-1.2.1}/podstack/__init__.py +1 -1
  4. {podstack-1.2.0 → podstack-1.2.1}/podstack/client.py +2 -2
  5. podstack-1.2.1/podstack.egg-info/PKG-INFO +467 -0
  6. {podstack-1.2.0 → podstack-1.2.1}/pyproject.toml +4 -4
  7. podstack-1.2.0/PKG-INFO +0 -299
  8. podstack-1.2.0/README.md +0 -247
  9. podstack-1.2.0/podstack.egg-info/PKG-INFO +0 -299
  10. {podstack-1.2.0 → podstack-1.2.1}/LICENSE +0 -0
  11. {podstack-1.2.0 → podstack-1.2.1}/podstack/annotations.py +0 -0
  12. {podstack-1.2.0 → podstack-1.2.1}/podstack/exceptions.py +0 -0
  13. {podstack-1.2.0 → podstack-1.2.1}/podstack/execution.py +0 -0
  14. {podstack-1.2.0 → podstack-1.2.1}/podstack/gpu_runner.py +0 -0
  15. {podstack-1.2.0 → podstack-1.2.1}/podstack/models.py +0 -0
  16. {podstack-1.2.0 → podstack-1.2.1}/podstack/notebook.py +0 -0
  17. {podstack-1.2.0 → podstack-1.2.1}/podstack/registry/__init__.py +0 -0
  18. {podstack-1.2.0 → podstack-1.2.1}/podstack/registry/client.py +0 -0
  19. {podstack-1.2.0 → podstack-1.2.1}/podstack/registry/exceptions.py +0 -0
  20. {podstack-1.2.0 → podstack-1.2.1}/podstack/registry/experiment.py +0 -0
  21. {podstack-1.2.0 → podstack-1.2.1}/podstack/registry/model.py +0 -0
  22. {podstack-1.2.0 → podstack-1.2.1}/podstack/registry/model_utils.py +0 -0
  23. {podstack-1.2.0 → podstack-1.2.1}/podstack.egg-info/SOURCES.txt +0 -0
  24. {podstack-1.2.0 → podstack-1.2.1}/podstack.egg-info/dependency_links.txt +0 -0
  25. {podstack-1.2.0 → podstack-1.2.1}/podstack.egg-info/requires.txt +0 -0
  26. {podstack-1.2.0 → podstack-1.2.1}/podstack.egg-info/top_level.txt +0 -0
  27. {podstack-1.2.0 → podstack-1.2.1}/podstack_gpu/__init__.py +0 -0
  28. {podstack-1.2.0 → podstack-1.2.1}/podstack_gpu/app.py +0 -0
  29. {podstack-1.2.0 → podstack-1.2.1}/podstack_gpu/exceptions.py +0 -0
  30. {podstack-1.2.0 → podstack-1.2.1}/podstack_gpu/image.py +0 -0
  31. {podstack-1.2.0 → podstack-1.2.1}/podstack_gpu/runner.py +0 -0
  32. {podstack-1.2.0 → podstack-1.2.1}/podstack_gpu/secret.py +0 -0
  33. {podstack-1.2.0 → podstack-1.2.1}/podstack_gpu/utils.py +0 -0
  34. {podstack-1.2.0 → podstack-1.2.1}/podstack_gpu/volume.py +0 -0
  35. {podstack-1.2.0 → podstack-1.2.1}/setup.cfg +0 -0
@@ -0,0 +1,467 @@
1
+ Metadata-Version: 2.4
2
+ Name: podstack
3
+ Version: 1.2.1
4
+ Summary: Official Python SDK for Podstack GPU Notebook Platform
5
+ Author-email: Podstack <support@podstack.ai>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://podstack.ai
8
+ Project-URL: Documentation, https://docs.podstack.ai
9
+ Project-URL: Repository, https://github.com/podstack/podstack-python
10
+ Project-URL: Issues, https://github.com/podstack/podstack-python/issues
11
+ Keywords: gpu,notebook,machine-learning,deep-learning,cloud,jupyter
12
+ Classifier: Development Status :: 5 - Production/Stable
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Intended Audience :: Science/Research
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.8
18
+ Classifier: Programming Language :: Python :: 3.9
19
+ Classifier: Programming Language :: Python :: 3.10
20
+ Classifier: Programming Language :: Python :: 3.11
21
+ Classifier: Programming Language :: Python :: 3.12
22
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
23
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
24
+ Requires-Python: >=3.8
25
+ Description-Content-Type: text/markdown
26
+ License-File: LICENSE
27
+ Requires-Dist: httpx>=0.24.0
28
+ Requires-Dist: requests>=2.28.0
29
+ Provides-Extra: torch
30
+ Requires-Dist: torch; extra == "torch"
31
+ Provides-Extra: tensorflow
32
+ Requires-Dist: tensorflow; extra == "tensorflow"
33
+ Provides-Extra: sklearn
34
+ Requires-Dist: scikit-learn; extra == "sklearn"
35
+ Provides-Extra: huggingface
36
+ Requires-Dist: transformers; extra == "huggingface"
37
+ Requires-Dist: safetensors; extra == "huggingface"
38
+ Provides-Extra: all
39
+ Requires-Dist: torch; extra == "all"
40
+ Requires-Dist: tensorflow; extra == "all"
41
+ Requires-Dist: scikit-learn; extra == "all"
42
+ Requires-Dist: transformers; extra == "all"
43
+ Requires-Dist: safetensors; extra == "all"
44
+ Provides-Extra: dev
45
+ Requires-Dist: pytest>=7.0.0; extra == "dev"
46
+ Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
47
+ Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
48
+ Requires-Dist: black>=23.0.0; extra == "dev"
49
+ Requires-Dist: mypy>=1.0.0; extra == "dev"
50
+ Requires-Dist: ruff>=0.0.270; extra == "dev"
51
+ Dynamic: license-file
52
+
53
+ # Podstack Python SDK
54
+
55
+ Official Python SDK for the Podstack GPU Platform. Run ML workloads on remote GPUs with simple decorators, track experiments, and manage models.
56
+
57
+ ## Installation
58
+
59
+ ```bash
60
+ pip install podstack
61
+ ```
62
+
63
+ With optional dependencies:
64
+
65
+ ```bash
66
+ pip install podstack[torch] # PyTorch support
67
+ pip install podstack[huggingface] # HuggingFace Transformers
68
+ pip install podstack[all] # All ML frameworks
69
+ ```
70
+
71
+ ## Quick Start
72
+
73
+ ```python
74
+ import podstack
75
+
76
+ # Initialize the SDK
77
+ podstack.init(
78
+ api_key="your-api-key",
79
+ project_id="your-project-id"
80
+ )
81
+
82
+ # Run a function on a remote GPU with a single decorator
83
+ @podstack.gpu(type="L40S", fraction=100)
84
+ def train():
85
+ import torch
86
+ print(f"GPU: {torch.cuda.get_device_name(0)}")
87
+ return {"status": "done"}
88
+
89
+ result = train() # Executes on remote GPU!
90
+ ```
91
+
92
+ ## Decorators & Annotations
93
+
94
+ Podstack provides decorators that turn any Python function into a remote GPU workload with built-in experiment tracking.
95
+
96
+ ### `@podstack.gpu` - Remote GPU Execution
97
+
98
+ ```python
99
+ import podstack
100
+
101
+ # Basic GPU execution
102
+ @podstack.gpu(type="L40S")
103
+ def train_model():
104
+ import torch
105
+ model = torch.nn.Linear(768, 10).cuda()
106
+ return {"params": sum(p.numel() for p in model.parameters())}
107
+
108
+ result = train_model()
109
+
110
+ # Specify GPU type, count, and fraction
111
+ @podstack.gpu(type="A100-80G", count=2, fraction=100)
112
+ def train_large_model():
113
+ import torch
114
+ print(f"GPUs available: {torch.cuda.device_count()}")
115
+
116
+ # Install pip packages on the fly
117
+ @podstack.gpu(type="L40S", pip=["transformers", "datasets", "accelerate"])
118
+ def finetune_llm():
119
+ from transformers import AutoModelForCausalLM, AutoTokenizer
120
+ model = AutoModelForCausalLM.from_pretrained("meta-llama/Llama-2-7b-hf")
121
+ ...
122
+
123
+ # Use uv for faster package installation
124
+ @podstack.gpu(type="L40S", uv=["torch", "transformers"])
125
+ def fast_setup():
126
+ ...
127
+
128
+ # Install from requirements.txt
129
+ @podstack.gpu(type="L40S", requirements="requirements.txt", use_uv=True)
130
+ def train_with_deps():
131
+ ...
132
+
133
+ # Use conda packages
134
+ @podstack.gpu(type="L40S", conda="cudatoolkit=11.8")
135
+ def train_with_conda():
136
+ ...
137
+
138
+ # Use a pre-built environment
139
+ @podstack.gpu(type="L40S", env="nlp")
140
+ def nlp_task():
141
+ ...
142
+
143
+ # Set execution timeout (default: 3600s)
144
+ @podstack.gpu(type="L40S", timeout=7200)
145
+ def long_training():
146
+ ...
147
+
148
+ # Disable remote execution (run locally for debugging)
149
+ @podstack.gpu(type="L40S", remote=False)
150
+ def debug_locally():
151
+ print("This runs on your local machine")
152
+
153
+ # Use as a context manager
154
+ with podstack.gpu(type="A100-80G", count=2) as cfg:
155
+ print(f"GPU config set: {cfg.type}")
156
+ ```
157
+
158
+ **Available GPU types:** `T4`, `L4`, `A10`, `L40S`, `A100-40G`, `A100-80G`, `H100`
159
+
160
+ **Available environments:** `ml`, `nlp`, `cv`, `audio`, `tabular`, `rl`, `scientific`
161
+
162
+ ### `@podstack.experiment` - Experiment Tracking
163
+
164
+ ```python
165
+ import podstack
166
+
167
+ # As a decorator
168
+ @podstack.experiment(name="transformer-experiments")
169
+ def run_experiment():
170
+ ...
171
+
172
+ # As a context manager
173
+ with podstack.experiment(name="transformer-experiments") as exp:
174
+ print(f"Experiment ID: {exp.id}")
175
+ ```
176
+
177
+ ### `@podstack.run` - Run Tracking
178
+
179
+ Automatically tracks execution time and GPU configuration.
180
+
181
+ ```python
182
+ import podstack
183
+
184
+ # As a decorator
185
+ @podstack.experiment(name="my-experiment")
186
+ @podstack.run(name="training-v1", track_gpu=True)
187
+ def train():
188
+ podstack.registry.log_params({"lr": 0.001, "batch_size": 32})
189
+ for epoch in range(10):
190
+ loss = 1.0 / (epoch + 1)
191
+ podstack.registry.log_metrics({"loss": loss}, step=epoch)
192
+
193
+ # As a context manager
194
+ with podstack.run(name="training-v1") as run:
195
+ podstack.registry.log_params({"lr": 0.001})
196
+ podstack.registry.log_metrics({"loss": 0.5}, step=1)
197
+ print(f"Run ID: {run.id}")
198
+
199
+ # With tags
200
+ @podstack.run(name="ablation-study", tags={"variant": "no-dropout"})
201
+ def ablation():
202
+ ...
203
+ ```
204
+
205
+ ### `@podstack.model` - Model Registration
206
+
207
+ ```python
208
+ import podstack
209
+
210
+ # Register model after function completes
211
+ @podstack.experiment(name="my-experiment")
212
+ @podstack.run(name="training-v1")
213
+ @podstack.model.register(name="my-classifier")
214
+ def train_and_save():
215
+ import torch
216
+ model = torch.nn.Linear(768, 10)
217
+ torch.save(model.state_dict(), "model.pt")
218
+ podstack.registry.log_artifact("model.pt", "model")
219
+
220
+ # Promote model to production after validation
221
+ @podstack.model.promote(name="my-classifier", version=1, stage="production")
222
+ def validate_and_promote():
223
+ # Run validation checks
224
+ accuracy = 0.95
225
+ assert accuracy > 0.90, "Model doesn't meet threshold"
226
+ ```
227
+
228
+ ### Combining Decorators
229
+
230
+ Stack decorators for a complete ML workflow:
231
+
232
+ ```python
233
+ import podstack
234
+
235
+ podstack.init(api_key="your-api-key", project_id="your-project-id")
236
+
237
+ @podstack.gpu(type="L40S", pip=["transformers", "datasets"])
238
+ @podstack.experiment(name="sentiment-analysis")
239
+ @podstack.run(name="bert-finetune-v1", track_gpu=True)
240
+ @podstack.model.register(name="sentiment-bert")
241
+ def full_pipeline():
242
+ from transformers import AutoModelForSequenceClassification, Trainer
243
+
244
+ model = AutoModelForSequenceClassification.from_pretrained("bert-base-uncased")
245
+
246
+ # Log hyperparameters
247
+ podstack.registry.log_params({
248
+ "model": "bert-base-uncased",
249
+ "learning_rate": 2e-5,
250
+ "epochs": 3
251
+ })
252
+
253
+ # Train...
254
+ podstack.registry.log_metrics({"accuracy": 0.92, "f1": 0.89})
255
+
256
+ return {"accuracy": 0.92}
257
+
258
+ result = full_pipeline() # Runs on remote L40S GPU with full tracking
259
+ ```
260
+
261
+ ## Registry - Experiment Tracking & Model Management
262
+
263
+ ### Initialize
264
+
265
+ ```python
266
+ from podstack import registry
267
+
268
+ registry.init(
269
+ api_key="your-api-key",
270
+ project_id="your-project-id"
271
+ )
272
+ ```
273
+
274
+ ### Track Experiments and Runs
275
+
276
+ ```python
277
+ from podstack import registry
278
+
279
+ # Set experiment
280
+ registry.set_experiment("my-experiment")
281
+
282
+ # Start a tracked run
283
+ with registry.start_run(name="training-v1") as run:
284
+ # Log hyperparameters
285
+ registry.log_params({
286
+ "learning_rate": 0.001,
287
+ "batch_size": 32,
288
+ "epochs": 10,
289
+ "optimizer": "adam"
290
+ })
291
+
292
+ # Log metrics at each step
293
+ for epoch in range(10):
294
+ loss = train_epoch()
295
+ accuracy = evaluate()
296
+ registry.log_metrics({"loss": loss, "accuracy": accuracy}, step=epoch)
297
+
298
+ # Set tags
299
+ registry.set_tag("framework", "pytorch")
300
+
301
+ # Log artifacts
302
+ registry.log_artifact("model.pt", "model")
303
+ registry.log_artifact("training_curves.png", "plots")
304
+
305
+ # Log dataset metadata
306
+ registry.log_dataset(
307
+ name="imdb-reviews",
308
+ path="s3://datasets/imdb",
309
+ num_rows=50000,
310
+ num_features=2
311
+ )
312
+ ```
313
+
314
+ ### Log and Load Models
315
+
316
+ ```python
317
+ from podstack import registry
318
+
319
+ # Log a model object (auto-detects framework)
320
+ registry.log_model(model, artifact_path="model", framework="pytorch")
321
+
322
+ # Register in model registry
323
+ registry.register_model(
324
+ name="my-classifier",
325
+ run_id=run.id,
326
+ description="BERT sentiment classifier"
327
+ )
328
+
329
+ # Promote to production
330
+ registry.set_model_stage("my-classifier", version=1, stage="production")
331
+
332
+ # Set aliases
333
+ registry.set_model_alias("my-classifier", alias="champion", version=1)
334
+
335
+ # Load model from registry
336
+ model = registry.load_model("my-classifier", stage="production")
337
+ ```
338
+
339
+ ### Compare Runs
340
+
341
+ ```python
342
+ from podstack import registry
343
+
344
+ # Compare multiple runs
345
+ comparison = registry.compare_runs(
346
+ run_ids=["run-id-1", "run-id-2", "run-id-3"],
347
+ metric_keys=["loss", "accuracy"]
348
+ )
349
+
350
+ # Get metric history for a run
351
+ history = registry.get_metric_history("run-id-1", "loss")
352
+ for point in history:
353
+ print(f"Step {point.step}: {point.value}")
354
+
355
+ # Search runs
356
+ runs = registry.search_runs(
357
+ experiment_id="exp-id",
358
+ status="completed",
359
+ max_results=50
360
+ )
361
+ ```
362
+
363
+ ### List and Browse
364
+
365
+ ```python
366
+ from podstack import registry
367
+
368
+ # List experiments
369
+ experiments = registry.list_experiments()
370
+
371
+ # List models
372
+ models = registry.list_models()
373
+
374
+ # Download artifacts
375
+ registry.download_artifact("run-id", "model/model.pt", "./downloads/")
376
+ ```
377
+
378
+ ## GPU Runner - Direct Code Execution
379
+
380
+ For running code strings directly on GPUs without decorators:
381
+
382
+ ```python
383
+ import podstack
384
+
385
+ podstack.init(api_key="your-api-key", project_id="your-project-id")
386
+
387
+ # Run code on a remote GPU
388
+ result = podstack.run_on_gpu('''
389
+ import torch
390
+ print(f"GPU: {torch.cuda.get_device_name(0)}")
391
+ print(f"Memory: {torch.cuda.get_device_properties(0).total_mem / 1e9:.1f} GB")
392
+ ''', gpu="L40S")
393
+
394
+ print(result.output)
395
+ print(f"Success: {result.success}")
396
+ print(f"Duration: {result.duration_seconds}s")
397
+ ```
398
+
399
+ ## Client API
400
+
401
+ For direct API access to notebooks and executions:
402
+
403
+ ```python
404
+ from podstack import Client
405
+
406
+ client = Client(api_key="your-api-key")
407
+
408
+ # Create a notebook
409
+ notebook = client.sync_create_notebook(name="experiment", gpu_type="L40S")
410
+ print(f"JupyterLab: {notebook.jupyter_url}")
411
+
412
+ # Run code
413
+ result = client.sync_run("print('Hello GPU!')", gpu_type="L40S")
414
+ print(result.output)
415
+ ```
416
+
417
+ ## Error Handling
418
+
419
+ ```python
420
+ from podstack import (
421
+ PodstackError,
422
+ AuthenticationError,
423
+ GPUNotAvailableError,
424
+ RateLimitError,
425
+ ExecutionTimeoutError
426
+ )
427
+
428
+ try:
429
+ result = train()
430
+ except AuthenticationError:
431
+ print("Invalid API key")
432
+ except GPUNotAvailableError as e:
433
+ print(f"GPU not available")
434
+ except RateLimitError as e:
435
+ print(f"Rate limited, retry after {e.retry_after}s")
436
+ except ExecutionTimeoutError as e:
437
+ print(f"Execution timed out: {e.execution_id}")
438
+ except PodstackError as e:
439
+ print(f"Error: {e.message}")
440
+ ```
441
+
442
+ ## Configuration
443
+
444
+ ```python
445
+ import podstack
446
+
447
+ # Option 1: Initialize explicitly
448
+ podstack.init(
449
+ api_key="your-api-key",
450
+ project_id="your-project-id",
451
+ api_url="https://api.podstack.ai/v1", # optional
452
+ registry_url="https://registry.podstack.ai" # optional
453
+ )
454
+
455
+ # Option 2: Environment variables
456
+ # PODSTACK_API_KEY=your-api-key
457
+ # PODSTACK_PROJECT_ID=your-project-id
458
+ # PODSTACK_API_URL=https://api.podstack.ai/v1
459
+ # PODSTACK_REGISTRY_URL=https://registry.podstack.ai
460
+
461
+ # Option 3: Auto-init (set PODSTACK_AUTO_INIT=1)
462
+ # SDK auto-initializes from env vars at import time
463
+ ```
464
+
465
+ ## License
466
+
467
+ MIT License - see LICENSE for details.