tetra-rp 0.13.0__py3-none-any.whl → 0.14.0__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.
Potentially problematic release.
This version of tetra-rp might be problematic. Click here for more details.
- tetra_rp/cli/commands/build.py +501 -0
- tetra_rp/cli/commands/init.py +106 -57
- tetra_rp/cli/commands/run.py +65 -87
- tetra_rp/cli/main.py +6 -4
- tetra_rp/cli/utils/conda.py +127 -0
- tetra_rp/cli/utils/ignore.py +139 -0
- tetra_rp/cli/utils/skeleton.py +317 -71
- tetra_rp/client.py +35 -8
- tetra_rp/core/resources/cpu.py +9 -0
- tetra_rp/core/resources/serverless_cpu.py +10 -2
- {tetra_rp-0.13.0.dist-info → tetra_rp-0.14.0.dist-info}/METADATA +2 -1
- {tetra_rp-0.13.0.dist-info → tetra_rp-0.14.0.dist-info}/RECORD +15 -18
- tetra_rp/cli/templates/advanced/main.py +0 -58
- tetra_rp/cli/templates/advanced/utils.py +0 -24
- tetra_rp/cli/templates/basic/main.py +0 -32
- tetra_rp/cli/templates/gpu-compute/main.py +0 -64
- tetra_rp/cli/templates/web-api/api.py +0 -67
- tetra_rp/cli/templates/web-api/main.py +0 -42
- {tetra_rp-0.13.0.dist-info → tetra_rp-0.14.0.dist-info}/WHEEL +0 -0
- {tetra_rp-0.13.0.dist-info → tetra_rp-0.14.0.dist-info}/entry_points.txt +0 -0
- {tetra_rp-0.13.0.dist-info → tetra_rp-0.14.0.dist-info}/top_level.txt +0 -0
tetra_rp/cli/utils/skeleton.py
CHANGED
|
@@ -1,101 +1,347 @@
|
|
|
1
1
|
"""Project skeleton creation utilities."""
|
|
2
2
|
|
|
3
3
|
from pathlib import Path
|
|
4
|
-
from typing import
|
|
4
|
+
from typing import List
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
# Template files content
|
|
7
|
+
MAIN_PY_TEMPLATE = '''"""
|
|
8
|
+
Flash Application - Flash Server
|
|
7
9
|
|
|
10
|
+
This is the main entry point for your Flash application.
|
|
11
|
+
It runs a FastAPI server that coordinates GPU workers.
|
|
12
|
+
"""
|
|
8
13
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
14
|
+
import asyncio
|
|
15
|
+
from fastapi import FastAPI
|
|
16
|
+
from pydantic import BaseModel
|
|
17
|
+
from dotenv import load_dotenv
|
|
12
18
|
|
|
19
|
+
from workers import ExampleWorker
|
|
13
20
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
template_dir = get_template_directory() / template_name
|
|
21
|
+
# Load environment variables
|
|
22
|
+
load_dotenv()
|
|
17
23
|
|
|
18
|
-
|
|
19
|
-
|
|
24
|
+
# Create FastAPI app
|
|
25
|
+
app = FastAPI(title="Flash Application")
|
|
20
26
|
|
|
21
|
-
files = {}
|
|
22
27
|
|
|
23
|
-
|
|
24
|
-
for
|
|
25
|
-
|
|
26
|
-
relative_path = file_path.name
|
|
28
|
+
class ProcessRequest(BaseModel):
|
|
29
|
+
"""Request model for processing endpoint."""
|
|
30
|
+
data: str
|
|
27
31
|
|
|
28
|
-
# Special handling for config.json - return as callable that generates tetra config
|
|
29
|
-
if file_path.name == "config.json":
|
|
30
|
-
config_content = file_path.read_text()
|
|
31
|
-
files[".tetra/config.json"] = lambda content=config_content: content
|
|
32
|
-
else:
|
|
33
|
-
files[relative_path] = file_path.read_text()
|
|
34
32
|
|
|
35
|
-
|
|
33
|
+
@app.get("/")
|
|
34
|
+
def home():
|
|
35
|
+
"""Health check endpoint."""
|
|
36
|
+
return {"status": "ok", "message": "Flash application running"}
|
|
36
37
|
|
|
37
38
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
@app.get("/health")
|
|
40
|
+
def health():
|
|
41
|
+
"""Health check endpoint."""
|
|
42
|
+
return {"healthy": True}
|
|
42
43
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
44
|
+
|
|
45
|
+
@app.post("/process")
|
|
46
|
+
async def process(request: ProcessRequest):
|
|
47
|
+
"""
|
|
48
|
+
Process data using GPU worker.
|
|
49
|
+
|
|
50
|
+
Example request:
|
|
51
|
+
{
|
|
52
|
+
"data": "test input"
|
|
49
53
|
}
|
|
54
|
+
"""
|
|
55
|
+
# Instantiate worker
|
|
56
|
+
worker = ExampleWorker()
|
|
57
|
+
|
|
58
|
+
# Call worker's process method
|
|
59
|
+
result = await worker.process({"input": request.data})
|
|
60
|
+
|
|
61
|
+
return result
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
if __name__ == "__main__":
|
|
65
|
+
import uvicorn
|
|
66
|
+
uvicorn.run(app, host="localhost", port=8888)
|
|
67
|
+
'''
|
|
68
|
+
|
|
69
|
+
WORKER_EXAMPLE_PY_TEMPLATE = '''"""
|
|
70
|
+
Example GPU Worker
|
|
71
|
+
|
|
72
|
+
This is an example of a GPU worker class that can be deployed
|
|
73
|
+
to RunPod serverless endpoints.
|
|
74
|
+
"""
|
|
75
|
+
|
|
76
|
+
from tetra_rp import remote, LiveServerless
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
# Configure GPU resource
|
|
80
|
+
config = LiveServerless(
|
|
81
|
+
name="example_worker",
|
|
82
|
+
workersMax=3,
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
@remote(config)
|
|
87
|
+
class ExampleWorker:
|
|
88
|
+
"""Example GPU worker for processing tasks."""
|
|
89
|
+
|
|
90
|
+
def __init__(self):
|
|
91
|
+
"""Initialize the worker."""
|
|
92
|
+
print("ExampleWorker initialized")
|
|
93
|
+
|
|
94
|
+
def process(self, input_data: dict) -> dict:
|
|
95
|
+
"""
|
|
96
|
+
Process input data and return result.
|
|
97
|
+
|
|
98
|
+
Args:
|
|
99
|
+
input_data: Dictionary with input parameters
|
|
100
|
+
|
|
101
|
+
Returns:
|
|
102
|
+
Dictionary with processing results
|
|
103
|
+
"""
|
|
104
|
+
# Your GPU processing logic here
|
|
105
|
+
result = {
|
|
106
|
+
"status": "success",
|
|
107
|
+
"input": input_data,
|
|
108
|
+
"output": f"Processed: {input_data}"
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return result
|
|
112
|
+
'''
|
|
113
|
+
|
|
114
|
+
WORKERS_INIT_PY_TEMPLATE = '''"""GPU Workers package."""
|
|
115
|
+
|
|
116
|
+
from .example_worker import ExampleWorker
|
|
117
|
+
|
|
118
|
+
__all__ = ["ExampleWorker"]
|
|
119
|
+
'''
|
|
120
|
+
|
|
121
|
+
ENV_EXAMPLE_TEMPLATE = """# RunPod API Configuration
|
|
122
|
+
RUNPOD_API_KEY=your_runpod_api_key_here
|
|
123
|
+
|
|
124
|
+
# Development settings
|
|
125
|
+
DEBUG=false
|
|
126
|
+
LOG_LEVEL=INFO
|
|
127
|
+
"""
|
|
128
|
+
|
|
129
|
+
REQUIREMENTS_TXT_TEMPLATE = """# Core dependencies for Flash
|
|
130
|
+
tetra-rp>=0.12.0
|
|
131
|
+
fastapi>=0.104.0
|
|
132
|
+
uvicorn[standard]>=0.24.0
|
|
133
|
+
python-dotenv>=1.0.0
|
|
134
|
+
pydantic>=2.0.0
|
|
135
|
+
aiohttp>=3.9.0
|
|
136
|
+
"""
|
|
137
|
+
|
|
138
|
+
GITIGNORE_TEMPLATE = """# Python
|
|
139
|
+
__pycache__/
|
|
140
|
+
*.py[cod]
|
|
141
|
+
*$py.class
|
|
142
|
+
*.so
|
|
143
|
+
.Python
|
|
144
|
+
env/
|
|
145
|
+
venv/
|
|
146
|
+
ENV/
|
|
147
|
+
build/
|
|
148
|
+
develop-eggs/
|
|
149
|
+
dist/
|
|
150
|
+
downloads/
|
|
151
|
+
eggs/
|
|
152
|
+
.eggs/
|
|
153
|
+
lib/
|
|
154
|
+
lib64/
|
|
155
|
+
parts/
|
|
156
|
+
sdist/
|
|
157
|
+
var/
|
|
158
|
+
wheels/
|
|
159
|
+
*.egg-info/
|
|
160
|
+
.installed.cfg
|
|
161
|
+
*.egg
|
|
162
|
+
|
|
163
|
+
# Environment
|
|
164
|
+
.env
|
|
165
|
+
.venv
|
|
166
|
+
|
|
167
|
+
# IDE
|
|
168
|
+
.vscode/
|
|
169
|
+
.idea/
|
|
170
|
+
*.swp
|
|
171
|
+
*.swo
|
|
172
|
+
*~
|
|
173
|
+
|
|
174
|
+
# Tetra
|
|
175
|
+
.tetra/
|
|
176
|
+
|
|
177
|
+
# OS
|
|
178
|
+
.DS_Store
|
|
179
|
+
Thumbs.db
|
|
180
|
+
"""
|
|
181
|
+
|
|
182
|
+
FLASHIGNORE_TEMPLATE = """# Flash build ignores
|
|
183
|
+
# Similar to .gitignore but specifically for flash build command
|
|
184
|
+
|
|
185
|
+
# Version control
|
|
186
|
+
.git/
|
|
187
|
+
.gitignore
|
|
188
|
+
|
|
189
|
+
# Python artifacts
|
|
190
|
+
__pycache__/
|
|
191
|
+
*.pyc
|
|
192
|
+
*.pyo
|
|
193
|
+
*.pyd
|
|
194
|
+
.Python
|
|
50
195
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
196
|
+
# Virtual environments
|
|
197
|
+
.env
|
|
198
|
+
.venv/
|
|
199
|
+
env/
|
|
200
|
+
venv/
|
|
201
|
+
ENV/
|
|
202
|
+
|
|
203
|
+
# Build artifacts
|
|
204
|
+
.build/
|
|
205
|
+
.tetra/
|
|
206
|
+
*.tar.gz
|
|
207
|
+
*.egg-info/
|
|
208
|
+
dist/
|
|
209
|
+
build/
|
|
210
|
+
|
|
211
|
+
# IDE files
|
|
212
|
+
.vscode/
|
|
213
|
+
.idea/
|
|
214
|
+
*.swp
|
|
215
|
+
*.swo
|
|
216
|
+
*~
|
|
217
|
+
|
|
218
|
+
# OS files
|
|
219
|
+
.DS_Store
|
|
220
|
+
Thumbs.db
|
|
221
|
+
|
|
222
|
+
# Test files
|
|
223
|
+
tests/
|
|
224
|
+
test_*.py
|
|
225
|
+
*_test.py
|
|
226
|
+
|
|
227
|
+
# Documentation (optional - comment out to include)
|
|
228
|
+
# docs/
|
|
229
|
+
# *.md
|
|
230
|
+
|
|
231
|
+
# Logs
|
|
232
|
+
*.log
|
|
233
|
+
"""
|
|
234
|
+
|
|
235
|
+
README_TEMPLATE = """# {{project_name}}
|
|
236
|
+
|
|
237
|
+
Flash application with Flash Server and GPU workers.
|
|
238
|
+
|
|
239
|
+
## Setup
|
|
240
|
+
|
|
241
|
+
1. Activate the conda environment:
|
|
242
|
+
```bash
|
|
243
|
+
conda activate {{project_name}}
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
2. Configure your RunPod API key:
|
|
247
|
+
```bash
|
|
248
|
+
cp .env.example .env
|
|
249
|
+
# Edit .env and add your RUNPOD_API_KEY
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
3. Run the development server:
|
|
253
|
+
```bash
|
|
254
|
+
flash run
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
## Project Structure
|
|
258
|
+
|
|
259
|
+
```
|
|
260
|
+
{{project_name}}/
|
|
261
|
+
├── main.py # Flash Server (FastAPI)
|
|
262
|
+
├── workers/ # GPU workers
|
|
263
|
+
│ ├── __init__.py
|
|
264
|
+
│ └── example_worker.py
|
|
265
|
+
├── .env.example # Environment variables template
|
|
266
|
+
├── requirements.txt # Python dependencies
|
|
267
|
+
└── README.md # This file
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
## Development
|
|
271
|
+
|
|
272
|
+
The Flash Server runs on `localhost:8888` and coordinates GPU workers.
|
|
273
|
+
|
|
274
|
+
### Adding New Workers
|
|
275
|
+
|
|
276
|
+
1. Create a new file in `workers/` directory
|
|
277
|
+
2. Define a class with `@remote` decorator
|
|
278
|
+
3. Import it in `workers/__init__.py`
|
|
279
|
+
4. Use it in `main.py`
|
|
280
|
+
|
|
281
|
+
Example:
|
|
282
|
+
```python
|
|
283
|
+
from tetra_rp import remote, LiveServerless
|
|
284
|
+
|
|
285
|
+
config = LiveServerless(name="my_worker", workersMax=3)
|
|
286
|
+
|
|
287
|
+
@remote(config)
|
|
288
|
+
class MyWorker:
|
|
289
|
+
def process(self, data):
|
|
290
|
+
return {{"result": f"Processed: {{data}}"}}
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
## Deployment
|
|
294
|
+
|
|
295
|
+
Deploy to production:
|
|
296
|
+
```bash
|
|
297
|
+
flash deploy send production
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
## Documentation
|
|
301
|
+
|
|
302
|
+
- [Flash CLI Docs](./docs/)
|
|
303
|
+
- [Tetra Documentation](https://docs.tetra.dev)
|
|
304
|
+
"""
|
|
305
|
+
|
|
306
|
+
|
|
307
|
+
def create_project_skeleton(project_dir: Path, force: bool = False) -> List[str]:
|
|
308
|
+
"""
|
|
309
|
+
Create Flash project skeleton.
|
|
310
|
+
|
|
311
|
+
Args:
|
|
312
|
+
project_dir: Project directory path
|
|
313
|
+
force: Overwrite existing files
|
|
314
|
+
|
|
315
|
+
Returns:
|
|
316
|
+
List of created file paths
|
|
317
|
+
"""
|
|
72
318
|
created_files = []
|
|
73
319
|
|
|
74
|
-
#
|
|
75
|
-
|
|
76
|
-
|
|
320
|
+
# Define project structure
|
|
321
|
+
files_to_create = {
|
|
322
|
+
"main.py": MAIN_PY_TEMPLATE,
|
|
323
|
+
"workers/__init__.py": WORKERS_INIT_PY_TEMPLATE,
|
|
324
|
+
"workers/example_worker.py": WORKER_EXAMPLE_PY_TEMPLATE,
|
|
325
|
+
".env.example": ENV_EXAMPLE_TEMPLATE,
|
|
326
|
+
"requirements.txt": REQUIREMENTS_TXT_TEMPLATE,
|
|
327
|
+
".gitignore": GITIGNORE_TEMPLATE,
|
|
328
|
+
".flashignore": FLASHIGNORE_TEMPLATE,
|
|
329
|
+
"README.md": README_TEMPLATE.format(project_name=project_dir.name),
|
|
330
|
+
}
|
|
77
331
|
|
|
78
|
-
# Create files
|
|
79
|
-
for
|
|
80
|
-
|
|
332
|
+
# Create files
|
|
333
|
+
for relative_path, content in files_to_create.items():
|
|
334
|
+
file_path = project_dir / relative_path
|
|
81
335
|
|
|
82
336
|
# Create parent directories if needed
|
|
83
|
-
|
|
337
|
+
file_path.parent.mkdir(parents=True, exist_ok=True)
|
|
84
338
|
|
|
85
339
|
# Skip existing files unless force is True
|
|
86
|
-
if
|
|
340
|
+
if file_path.exists() and not force:
|
|
87
341
|
continue
|
|
88
342
|
|
|
89
|
-
# Get content (could be string or callable)
|
|
90
|
-
if callable(content):
|
|
91
|
-
file_content = content()
|
|
92
|
-
else:
|
|
93
|
-
file_content = content
|
|
94
|
-
|
|
95
343
|
# Write file
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
created_files.append(str(path))
|
|
344
|
+
file_path.write_text(content)
|
|
345
|
+
created_files.append(str(file_path.relative_to(project_dir)))
|
|
100
346
|
|
|
101
347
|
return created_files
|
tetra_rp/client.py
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import os
|
|
1
2
|
import inspect
|
|
2
3
|
import logging
|
|
3
4
|
from functools import wraps
|
|
@@ -15,31 +16,37 @@ def remote(
|
|
|
15
16
|
dependencies: Optional[List[str]] = None,
|
|
16
17
|
system_dependencies: Optional[List[str]] = None,
|
|
17
18
|
accelerate_downloads: bool = True,
|
|
19
|
+
local: bool = False,
|
|
18
20
|
**extra,
|
|
19
21
|
):
|
|
20
22
|
"""
|
|
21
23
|
Decorator to enable dynamic resource provisioning and dependency management for serverless functions.
|
|
22
24
|
|
|
23
25
|
This decorator allows a function to be executed in a remote serverless environment, with support for
|
|
24
|
-
dynamic resource provisioning and installation of required dependencies.
|
|
26
|
+
dynamic resource provisioning and installation of required dependencies. It can also bypass remote
|
|
27
|
+
execution entirely for local testing.
|
|
25
28
|
|
|
26
29
|
Args:
|
|
27
30
|
resource_config (ServerlessResource): Configuration object specifying the serverless resource
|
|
28
|
-
to be provisioned or used.
|
|
31
|
+
to be provisioned or used. Not used when local=True.
|
|
29
32
|
dependencies (List[str], optional): A list of pip package names to be installed in the remote
|
|
30
|
-
environment before executing the function. Defaults to None.
|
|
33
|
+
environment before executing the function. Not used when local=True. Defaults to None.
|
|
31
34
|
system_dependencies (List[str], optional): A list of system packages to be installed in the remote
|
|
32
|
-
environment before executing the function. Defaults to None.
|
|
35
|
+
environment before executing the function. Not used when local=True. Defaults to None.
|
|
33
36
|
accelerate_downloads (bool, optional): Enable download acceleration for dependencies and models.
|
|
34
|
-
Defaults to True.
|
|
37
|
+
Only applies to remote execution. Defaults to True.
|
|
38
|
+
local (bool, optional): Execute function/class locally instead of provisioning remote servers.
|
|
39
|
+
Returns the unwrapped function/class for direct local execution. Users must ensure all required
|
|
40
|
+
dependencies are already installed in their local environment. Defaults to False.
|
|
35
41
|
extra (dict, optional): Additional parameters for the execution of the resource. Defaults to an empty dict.
|
|
36
42
|
|
|
37
43
|
Returns:
|
|
38
|
-
Callable: A decorator that wraps the target function, enabling remote execution with the
|
|
39
|
-
|
|
44
|
+
Callable: A decorator that wraps the target function, enabling remote execution with the specified
|
|
45
|
+
resource configuration and dependencies, or returns the unwrapped function/class for local execution.
|
|
40
46
|
|
|
41
47
|
Example:
|
|
42
48
|
```python
|
|
49
|
+
# Remote execution (production)
|
|
43
50
|
@remote(
|
|
44
51
|
resource_config=my_resource_config,
|
|
45
52
|
dependencies=["numpy", "pandas"],
|
|
@@ -48,10 +55,30 @@ def remote(
|
|
|
48
55
|
async def my_function(data):
|
|
49
56
|
# Function logic here
|
|
50
57
|
pass
|
|
58
|
+
|
|
59
|
+
# Local execution (testing/development)
|
|
60
|
+
# Note: Ensure numpy and pandas are installed locally first
|
|
61
|
+
@remote(
|
|
62
|
+
resource_config=my_resource_config,
|
|
63
|
+
dependencies=["numpy", "pandas"], # Only used for remote execution
|
|
64
|
+
local=True,
|
|
65
|
+
)
|
|
66
|
+
async def my_test_function(data):
|
|
67
|
+
# Runs locally - dependencies must be pre-installed
|
|
68
|
+
pass
|
|
51
69
|
```
|
|
52
70
|
"""
|
|
53
71
|
|
|
54
72
|
def decorator(func_or_class):
|
|
73
|
+
if os.getenv("RUNPOD_POD_ID") or os.getenv("RUNPOD_ENDPOINT_ID"):
|
|
74
|
+
# Worker mode when running on RunPod platform
|
|
75
|
+
return func_or_class
|
|
76
|
+
|
|
77
|
+
# Local execution mode - execute without provisioning remote servers
|
|
78
|
+
if local:
|
|
79
|
+
return func_or_class
|
|
80
|
+
|
|
81
|
+
# Remote execution mode
|
|
55
82
|
if inspect.isclass(func_or_class):
|
|
56
83
|
# Handle class decoration
|
|
57
84
|
return create_remote_class(
|
|
@@ -63,7 +90,7 @@ def remote(
|
|
|
63
90
|
extra,
|
|
64
91
|
)
|
|
65
92
|
else:
|
|
66
|
-
# Handle function decoration
|
|
93
|
+
# Handle function decoration
|
|
67
94
|
@wraps(func_or_class)
|
|
68
95
|
async def wrapper(*args, **kwargs):
|
|
69
96
|
resource_manager = ResourceManager()
|
tetra_rp/core/resources/cpu.py
CHANGED
|
@@ -16,6 +16,9 @@ class CpuInstanceType(str, Enum):
|
|
|
16
16
|
- cpu5g: Not available
|
|
17
17
|
"""
|
|
18
18
|
|
|
19
|
+
ANY = "any"
|
|
20
|
+
"""Any CPU"""
|
|
21
|
+
|
|
19
22
|
# 3rd Generation General Purpose (RAM multiplier: 4.0)
|
|
20
23
|
|
|
21
24
|
CPU3G_1_4 = "cpu3g-1-4"
|
|
@@ -58,6 +61,11 @@ class CpuInstanceType(str, Enum):
|
|
|
58
61
|
CPU5C_8_16 = "cpu5c-8-16"
|
|
59
62
|
"""8 vCPU, 16GB RAM, max 120GB container disk"""
|
|
60
63
|
|
|
64
|
+
@classmethod
|
|
65
|
+
def all(cls) -> List["CpuInstanceType"]:
|
|
66
|
+
"""Returns all CPU Instance Types."""
|
|
67
|
+
return [c for c in cls if c != cls.ANY]
|
|
68
|
+
|
|
61
69
|
|
|
62
70
|
def calculate_max_disk_size(instance_type: CpuInstanceType) -> int:
|
|
63
71
|
"""
|
|
@@ -104,6 +112,7 @@ def calculate_max_disk_size(instance_type: CpuInstanceType) -> int:
|
|
|
104
112
|
CPU_INSTANCE_DISK_LIMITS = {
|
|
105
113
|
instance_type: calculate_max_disk_size(instance_type)
|
|
106
114
|
for instance_type in CpuInstanceType
|
|
115
|
+
if instance_type != CpuInstanceType.ANY
|
|
107
116
|
}
|
|
108
117
|
|
|
109
118
|
|
|
@@ -6,7 +6,7 @@ This module contains all CPU-related serverless functionality, separate from GPU
|
|
|
6
6
|
|
|
7
7
|
from typing import List, Optional
|
|
8
8
|
|
|
9
|
-
from pydantic import field_serializer, model_validator
|
|
9
|
+
from pydantic import field_serializer, model_validator, field_validator
|
|
10
10
|
|
|
11
11
|
from .cpu import (
|
|
12
12
|
CpuInstanceType,
|
|
@@ -105,7 +105,7 @@ class CpuServerlessEndpoint(CpuEndpointMixin, ServerlessEndpoint):
|
|
|
105
105
|
Represents a CPU-only serverless endpoint distinct from a live serverless.
|
|
106
106
|
"""
|
|
107
107
|
|
|
108
|
-
instanceIds: Optional[List[CpuInstanceType]] = [CpuInstanceType.
|
|
108
|
+
instanceIds: Optional[List[CpuInstanceType]] = [CpuInstanceType.ANY]
|
|
109
109
|
|
|
110
110
|
def _create_new_template(self) -> PodTemplate:
|
|
111
111
|
"""Create a new PodTemplate with CPU-appropriate disk sizing."""
|
|
@@ -133,6 +133,14 @@ class CpuServerlessEndpoint(CpuEndpointMixin, ServerlessEndpoint):
|
|
|
133
133
|
# Apply CPU-specific disk sizing
|
|
134
134
|
self._apply_cpu_disk_sizing(self.template)
|
|
135
135
|
|
|
136
|
+
@field_validator("instanceIds")
|
|
137
|
+
@classmethod
|
|
138
|
+
def validate_cpus(cls, value: List[CpuInstanceType]) -> List[CpuInstanceType]:
|
|
139
|
+
"""Expand ANY to all GPU groups"""
|
|
140
|
+
if value == [CpuInstanceType.ANY]:
|
|
141
|
+
return CpuInstanceType.all()
|
|
142
|
+
return value
|
|
143
|
+
|
|
136
144
|
@model_validator(mode="after")
|
|
137
145
|
def set_serverless_template(self):
|
|
138
146
|
# Sync CPU-specific fields first
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tetra_rp
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.14.0
|
|
4
4
|
Summary: A Python library for distributed inference and serving of machine learning models
|
|
5
5
|
Author-email: Marut Pandya <pandyamarut@gmail.com>, Patrick Rachford <prachford@icloud.com>, Dean Quinanola <dean.quinanola@runpod.io>
|
|
6
6
|
License: MIT
|
|
@@ -17,6 +17,7 @@ Requires-Dist: pydantic>=2.0.0
|
|
|
17
17
|
Requires-Dist: rich>=14.0.0
|
|
18
18
|
Requires-Dist: typer>=0.12.0
|
|
19
19
|
Requires-Dist: questionary>=2.0.0
|
|
20
|
+
Requires-Dist: pathspec>=0.11.0
|
|
20
21
|
|
|
21
22
|
# Tetra: Serverless computing for AI workloads
|
|
22
23
|
|
|
@@ -1,24 +1,21 @@
|
|
|
1
1
|
tetra_rp/__init__.py,sha256=_D3Wbtv9tBh_WGS4Si5uQbsefL63GqqjoGTN3R8P6fA,769
|
|
2
|
-
tetra_rp/client.py,sha256=
|
|
2
|
+
tetra_rp/client.py,sha256=ZQCQhpO0zquRhyAcuwX5_Ed5qm06o57M-Zixg2qXZf4,4428
|
|
3
3
|
tetra_rp/config.py,sha256=9FYzouOam0PVoBIITpwHu1N5dGd1ueLHjWMaZYmdquI,760
|
|
4
4
|
tetra_rp/execute_class.py,sha256=pm-wupP_rGwlmS_3B5O2g8a5qINlVSWuGUc1E7pveUw,12075
|
|
5
5
|
tetra_rp/logger.py,sha256=gk5-PWp3k_GQ5DxndsRkBCX0jarp_3lgZ1oiTFuThQg,1125
|
|
6
6
|
tetra_rp/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
7
|
-
tetra_rp/cli/main.py,sha256=
|
|
7
|
+
tetra_rp/cli/main.py,sha256=uSW6ugLXMsux9O6tpoShWHztM2-PxylRac-6DJsKagA,2171
|
|
8
8
|
tetra_rp/cli/commands/__init__.py,sha256=gQ6tnU0Rvm0-ESWFUBU-KDl5dpNOpUTG509hXOQQjwY,27
|
|
9
|
+
tetra_rp/cli/commands/build.py,sha256=4ADJgseMzFTasrpBMG7ExEy7hH5sI0r0QWU_EuAuuEA,15488
|
|
9
10
|
tetra_rp/cli/commands/deploy.py,sha256=dznG7NI04ihfccn5YIjBbIxMRM19h-B60jTTWazGppc,10609
|
|
10
|
-
tetra_rp/cli/commands/init.py,sha256=
|
|
11
|
+
tetra_rp/cli/commands/init.py,sha256=LKQ52NBsmfvpNV2goHUogzU1gekPkNfno4SHN72g21I,4837
|
|
11
12
|
tetra_rp/cli/commands/resource.py,sha256=XMsSAYaCtw42tUz7vJsK53lZRrKX51fMMfQv8sdExlc,5679
|
|
12
|
-
tetra_rp/cli/commands/run.py,sha256=
|
|
13
|
-
tetra_rp/cli/templates/advanced/main.py,sha256=gfPETln1Re0R7Ysd8WlMon1myFmCtpJk6k6a1AGnK0Q,1221
|
|
14
|
-
tetra_rp/cli/templates/advanced/utils.py,sha256=8BfZW2_qXS7bYyiO62KhEib_TqUfIxer2jqXoIctK1c,647
|
|
15
|
-
tetra_rp/cli/templates/basic/main.py,sha256=fItaje-ahvQKsvVcA_HNVCy0grw9fLb1kd07eU5jvAQ,677
|
|
16
|
-
tetra_rp/cli/templates/gpu-compute/main.py,sha256=x-8W2ciT_bnLACcdKrMPwX4HqkLCeX-RKC1E6IzXnAI,1602
|
|
17
|
-
tetra_rp/cli/templates/web-api/api.py,sha256=7ucd6Mg9Y3aVNuG21Jh_ToiBWe0R3NaYIN-dExaRN_U,2009
|
|
18
|
-
tetra_rp/cli/templates/web-api/main.py,sha256=lRu0CVbPuCfvVQrp5IQf4KlR1dpC70fd7J008GXmtvs,846
|
|
13
|
+
tetra_rp/cli/commands/run.py,sha256=auTGa6k8tKTlwjodtV6c7qNczC5a0fyJfg4hQZ9Qc9w,2779
|
|
19
14
|
tetra_rp/cli/utils/__init__.py,sha256=Ytcdqe_Kzy37LSnsBj1Drkrx0Uo7TWExjQZ2mwW_nMg,27
|
|
15
|
+
tetra_rp/cli/utils/conda.py,sha256=Lj_ddXxysAFboR-Hd6wTM-mrV6TBEnQzKhEgxjUQdPo,3514
|
|
20
16
|
tetra_rp/cli/utils/deployment.py,sha256=2hskoGEnZYTJMR2on37X4kaQEtBDCKoWK_7RQr1VEY0,5123
|
|
21
|
-
tetra_rp/cli/utils/
|
|
17
|
+
tetra_rp/cli/utils/ignore.py,sha256=rHyjuCboa4N4JAqgLr0f_xYzzQSt8mb1dsDDc85EBD0,3763
|
|
18
|
+
tetra_rp/cli/utils/skeleton.py,sha256=p_aIodEX_gbH8hRNl_i1SFz-biz4REi0jG4j9F9wgQ4,6301
|
|
22
19
|
tetra_rp/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
23
20
|
tetra_rp/core/api/__init__.py,sha256=oldrEKMwxYoBPLvPfVlaFS3wfUtTTxCN6-HzlpTh6vE,124
|
|
24
21
|
tetra_rp/core/api/runpod.py,sha256=3TTx1fkXMLZ2R5JCrQYPEn8dhdUsBt8i5OEwAfaKQ_k,10451
|
|
@@ -26,14 +23,14 @@ tetra_rp/core/resources/__init__.py,sha256=ZvSfceYV4S1Xo3YA03B-sR5VRud8BKfx5Pe44
|
|
|
26
23
|
tetra_rp/core/resources/base.py,sha256=UJeDiFN45aO1n5SBcxn56ohLhj-AWHoj0KO7mF4yJ_o,1440
|
|
27
24
|
tetra_rp/core/resources/cloud.py,sha256=XJOWPfzYlDVJGHxgffcfpEaOKrWhGdi7AzTlaGuYj0o,70
|
|
28
25
|
tetra_rp/core/resources/constants.py,sha256=F1gPqFaXcCmfrbUSO9PQtUBv984TxFc3pySgVy-kXk8,158
|
|
29
|
-
tetra_rp/core/resources/cpu.py,sha256=
|
|
26
|
+
tetra_rp/core/resources/cpu.py,sha256=WW7Yg6CXrzH7GnQeqMa80oKHs2TdNmL05uQLvi5C3SQ,4198
|
|
30
27
|
tetra_rp/core/resources/environment.py,sha256=FC9kJCa8YLSar75AKUKqJYnNLrUdjZj8ZTOrspBrS00,1267
|
|
31
28
|
tetra_rp/core/resources/gpu.py,sha256=mMOPLhBugFBAMAl3ezhjAxKuvYya5_9A_h7kvaCoAfk,1885
|
|
32
29
|
tetra_rp/core/resources/live_serverless.py,sha256=FLmaQdn5UMczEfkP3qykIfRVfZeyYdvyNHX9Nd13_54,1868
|
|
33
30
|
tetra_rp/core/resources/network_volume.py,sha256=h_1xhrbBm9jJWROOGl5qy9u4_kCKSyV4idzt0567-J8,5193
|
|
34
31
|
tetra_rp/core/resources/resource_manager.py,sha256=K-SgCk2BMNEAnkB87YynxUH-suZcdcOPLMonL7EogIw,4988
|
|
35
32
|
tetra_rp/core/resources/serverless.py,sha256=1T21RkMjGnM1I87AsGQ6qazp7A9cE7LwH_c6yJ5shPQ,13427
|
|
36
|
-
tetra_rp/core/resources/serverless_cpu.py,sha256=
|
|
33
|
+
tetra_rp/core/resources/serverless_cpu.py,sha256=vDWVU3ck8IpBMCsg9KIOW9adivSqE3lM975EzdUstJw,5863
|
|
37
34
|
tetra_rp/core/resources/template.py,sha256=qQ8Wd7Rzr1_YeAbW1V7_k7AVHzgWR_RPjcaRfKsetAk,3141
|
|
38
35
|
tetra_rp/core/resources/utils.py,sha256=mgXfgz_NuHN_IC7TzMNdH9II-LMjxcDCG7syDTcPiGs,1721
|
|
39
36
|
tetra_rp/core/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -49,8 +46,8 @@ tetra_rp/stubs/__init__.py,sha256=ozKsHs8q0T7o2qhQEquub9hqomh1Htys53mMraaRu2E,72
|
|
|
49
46
|
tetra_rp/stubs/live_serverless.py,sha256=gIjhizgX5MDifxXo5JBONS3fmGipwRAgv9_sydc_cxU,4451
|
|
50
47
|
tetra_rp/stubs/registry.py,sha256=OdqAHFJIhPBAaR-S_spJNgRwpO96xEqhfAENhomqmI4,3235
|
|
51
48
|
tetra_rp/stubs/serverless.py,sha256=BM_a5Ml5VADBYu2WRNmo9qnicP8NnXDGl5ywifulbD0,947
|
|
52
|
-
tetra_rp-0.
|
|
53
|
-
tetra_rp-0.
|
|
54
|
-
tetra_rp-0.
|
|
55
|
-
tetra_rp-0.
|
|
56
|
-
tetra_rp-0.
|
|
49
|
+
tetra_rp-0.14.0.dist-info/METADATA,sha256=Hbv6dJ2l0XlyMhvt9YJ0YWP3CETzi6RcWAY6Hjx5vqs,28214
|
|
50
|
+
tetra_rp-0.14.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
51
|
+
tetra_rp-0.14.0.dist-info/entry_points.txt,sha256=FJi3ytBLKCcyz4tXJhOM3XNKzTxpnl3AauiPH2lHvWY,48
|
|
52
|
+
tetra_rp-0.14.0.dist-info/top_level.txt,sha256=bBay7JTDwJXsTYvVjrwno9hnF-j0q272lk65f2AcPjU,9
|
|
53
|
+
tetra_rp-0.14.0.dist-info/RECORD,,
|