kubetorch 0.2.5__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.
- kubetorch/__init__.py +59 -0
- kubetorch/cli.py +1939 -0
- kubetorch/cli_utils.py +967 -0
- kubetorch/config.py +453 -0
- kubetorch/constants.py +18 -0
- kubetorch/docs/Makefile +18 -0
- kubetorch/docs/__init__.py +0 -0
- kubetorch/docs/_ext/json_globaltoc.py +42 -0
- kubetorch/docs/api/cli.rst +10 -0
- kubetorch/docs/api/python/app.rst +21 -0
- kubetorch/docs/api/python/cls.rst +19 -0
- kubetorch/docs/api/python/compute.rst +25 -0
- kubetorch/docs/api/python/config.rst +11 -0
- kubetorch/docs/api/python/fn.rst +19 -0
- kubetorch/docs/api/python/image.rst +14 -0
- kubetorch/docs/api/python/secret.rst +18 -0
- kubetorch/docs/api/python/volumes.rst +13 -0
- kubetorch/docs/api/python.rst +101 -0
- kubetorch/docs/conf.py +69 -0
- kubetorch/docs/index.rst +20 -0
- kubetorch/docs/requirements.txt +5 -0
- kubetorch/globals.py +269 -0
- kubetorch/logger.py +59 -0
- kubetorch/resources/__init__.py +0 -0
- kubetorch/resources/callables/__init__.py +0 -0
- kubetorch/resources/callables/cls/__init__.py +0 -0
- kubetorch/resources/callables/cls/cls.py +159 -0
- kubetorch/resources/callables/fn/__init__.py +0 -0
- kubetorch/resources/callables/fn/fn.py +140 -0
- kubetorch/resources/callables/module.py +1315 -0
- kubetorch/resources/callables/utils.py +203 -0
- kubetorch/resources/compute/__init__.py +0 -0
- kubetorch/resources/compute/app.py +253 -0
- kubetorch/resources/compute/compute.py +2414 -0
- kubetorch/resources/compute/decorators.py +137 -0
- kubetorch/resources/compute/utils.py +1026 -0
- kubetorch/resources/compute/websocket.py +135 -0
- kubetorch/resources/images/__init__.py +1 -0
- kubetorch/resources/images/image.py +412 -0
- kubetorch/resources/images/images.py +64 -0
- kubetorch/resources/secrets/__init__.py +2 -0
- kubetorch/resources/secrets/kubernetes_secrets_client.py +377 -0
- kubetorch/resources/secrets/provider_secrets/__init__.py +0 -0
- kubetorch/resources/secrets/provider_secrets/anthropic_secret.py +12 -0
- kubetorch/resources/secrets/provider_secrets/aws_secret.py +16 -0
- kubetorch/resources/secrets/provider_secrets/azure_secret.py +14 -0
- kubetorch/resources/secrets/provider_secrets/cohere_secret.py +12 -0
- kubetorch/resources/secrets/provider_secrets/gcp_secret.py +16 -0
- kubetorch/resources/secrets/provider_secrets/github_secret.py +13 -0
- kubetorch/resources/secrets/provider_secrets/huggingface_secret.py +20 -0
- kubetorch/resources/secrets/provider_secrets/kubeconfig_secret.py +12 -0
- kubetorch/resources/secrets/provider_secrets/lambda_secret.py +13 -0
- kubetorch/resources/secrets/provider_secrets/langchain_secret.py +12 -0
- kubetorch/resources/secrets/provider_secrets/openai_secret.py +11 -0
- kubetorch/resources/secrets/provider_secrets/pinecone_secret.py +12 -0
- kubetorch/resources/secrets/provider_secrets/providers.py +92 -0
- kubetorch/resources/secrets/provider_secrets/ssh_secret.py +12 -0
- kubetorch/resources/secrets/provider_secrets/wandb_secret.py +11 -0
- kubetorch/resources/secrets/secret.py +224 -0
- kubetorch/resources/secrets/secret_factory.py +64 -0
- kubetorch/resources/secrets/utils.py +222 -0
- kubetorch/resources/volumes/__init__.py +0 -0
- kubetorch/resources/volumes/volume.py +340 -0
- kubetorch/servers/__init__.py +0 -0
- kubetorch/servers/http/__init__.py +0 -0
- kubetorch/servers/http/distributed_utils.py +2968 -0
- kubetorch/servers/http/http_client.py +802 -0
- kubetorch/servers/http/http_server.py +1622 -0
- kubetorch/servers/http/server_metrics.py +255 -0
- kubetorch/servers/http/utils.py +722 -0
- kubetorch/serving/__init__.py +0 -0
- kubetorch/serving/autoscaling.py +153 -0
- kubetorch/serving/base_service_manager.py +344 -0
- kubetorch/serving/constants.py +77 -0
- kubetorch/serving/deployment_service_manager.py +431 -0
- kubetorch/serving/knative_service_manager.py +487 -0
- kubetorch/serving/raycluster_service_manager.py +526 -0
- kubetorch/serving/service_manager.py +18 -0
- kubetorch/serving/templates/deployment_template.yaml +17 -0
- kubetorch/serving/templates/knative_service_template.yaml +19 -0
- kubetorch/serving/templates/kt_setup_template.sh.j2 +91 -0
- kubetorch/serving/templates/pod_template.yaml +198 -0
- kubetorch/serving/templates/raycluster_service_template.yaml +42 -0
- kubetorch/serving/templates/raycluster_template.yaml +35 -0
- kubetorch/serving/templates/service_template.yaml +21 -0
- kubetorch/serving/templates/workerset_template.yaml +36 -0
- kubetorch/serving/utils.py +344 -0
- kubetorch/utils.py +263 -0
- kubetorch-0.2.5.dist-info/METADATA +75 -0
- kubetorch-0.2.5.dist-info/RECORD +92 -0
- kubetorch-0.2.5.dist-info/WHEEL +4 -0
- kubetorch-0.2.5.dist-info/entry_points.txt +5 -0
kubetorch/utils.py
ADDED
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
import enum
|
|
2
|
+
import json
|
|
3
|
+
import os
|
|
4
|
+
import re
|
|
5
|
+
import subprocess
|
|
6
|
+
import sys
|
|
7
|
+
from datetime import datetime, timezone
|
|
8
|
+
from io import StringIO
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
from urllib.parse import urlparse
|
|
11
|
+
|
|
12
|
+
from kubernetes import client, config
|
|
13
|
+
|
|
14
|
+
from kubetorch.constants import DEFAULT_KUBECONFIG_PATH, MAX_USERNAME_LENGTH
|
|
15
|
+
from kubetorch.globals import config as kt_config
|
|
16
|
+
from kubetorch.logger import get_logger
|
|
17
|
+
from kubetorch.resources.callables.utils import get_local_install_path
|
|
18
|
+
|
|
19
|
+
logger = get_logger(__name__)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def extract_host_port(url: str):
|
|
23
|
+
"""Extract host and port when needed separately from a URL."""
|
|
24
|
+
p = urlparse(url)
|
|
25
|
+
return p.hostname, (p.port or (443 if p.scheme == "https" else 80))
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def http_to_ws(url: str) -> str:
|
|
29
|
+
"""Convert HTTP/HTTPS URLs to WebSocket URLs, or return as-is if already WS."""
|
|
30
|
+
if url.startswith("https://"):
|
|
31
|
+
return "wss://" + url[len("https://") :]
|
|
32
|
+
if url.startswith("http://"):
|
|
33
|
+
return "ws://" + url[len("http://") :]
|
|
34
|
+
if url.startswith(("ws://", "wss://")):
|
|
35
|
+
return url # already WebSocket URL
|
|
36
|
+
# Default to ws:// for bare hostnames
|
|
37
|
+
return "ws://" + url
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def validate_username(username):
|
|
41
|
+
if username is None: # will be used in case we run kt config user username
|
|
42
|
+
return username
|
|
43
|
+
# Kubernetes requires service names to follow DNS-1035 label standards
|
|
44
|
+
original_username = username # if an exception is raised because the username is invalid, we want to print the original provided name
|
|
45
|
+
username = username.lower().replace("_", "-").replace("/", "-")
|
|
46
|
+
# Make sure the first character is a letter
|
|
47
|
+
if not re.match(r"^[a-z]", username):
|
|
48
|
+
# Strip out all the characters before the first letter with a regex
|
|
49
|
+
username = re.sub(r"^[^a-z]*", "", username)
|
|
50
|
+
username = username[:MAX_USERNAME_LENGTH]
|
|
51
|
+
# Make sure username doesn't end or start with a hyphen
|
|
52
|
+
if username.startswith("-") or username.endswith("-"):
|
|
53
|
+
username = username.strip("-")
|
|
54
|
+
reserved = ["kt", "kubetorch", "knative"]
|
|
55
|
+
if username in reserved:
|
|
56
|
+
raise ValueError(f"{original_username} is one of the reserved names: {', '.join(reserved)}")
|
|
57
|
+
if not re.match(r"^[a-z]([-a-z0-9]*[a-z0-9])?$", username):
|
|
58
|
+
raise ValueError(f"{original_username} must be a valid k8s name")
|
|
59
|
+
return username
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def load_kubeconfig():
|
|
63
|
+
try:
|
|
64
|
+
config.load_incluster_config()
|
|
65
|
+
except config.config_exception.ConfigException:
|
|
66
|
+
kubeconfig_path = os.getenv("KUBECONFIG") or DEFAULT_KUBECONFIG_PATH
|
|
67
|
+
abs_path = Path(kubeconfig_path).expanduser()
|
|
68
|
+
if not abs_path.exists():
|
|
69
|
+
raise FileNotFoundError(f"Kubeconfig file not found in path: {abs_path}")
|
|
70
|
+
config.load_kube_config(str(abs_path))
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def current_git_branch():
|
|
74
|
+
try:
|
|
75
|
+
# For CI env
|
|
76
|
+
branch = (
|
|
77
|
+
os.environ.get("GITHUB_HEAD_REF") # PRs: source branch name
|
|
78
|
+
or os.environ.get("GITHUB_REF_NAME") # Pushes: branch name
|
|
79
|
+
or os.environ.get("CI_COMMIT_REF_NAME") # GitLab
|
|
80
|
+
or os.environ.get("CIRCLE_BRANCH") # CircleCI
|
|
81
|
+
)
|
|
82
|
+
if not branch:
|
|
83
|
+
branch = (
|
|
84
|
+
subprocess.check_output(
|
|
85
|
+
["git", "rev-parse", "--abbrev-ref", "HEAD"],
|
|
86
|
+
stderr=subprocess.DEVNULL,
|
|
87
|
+
)
|
|
88
|
+
.decode("utf-8")
|
|
89
|
+
.strip()
|
|
90
|
+
)
|
|
91
|
+
return branch
|
|
92
|
+
except Exception as e:
|
|
93
|
+
logger.debug(f"Failed to load current git branch: {e}")
|
|
94
|
+
return None
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def iso_timestamp_to_nanoseconds(timestamp):
|
|
98
|
+
if timestamp is None:
|
|
99
|
+
dt = datetime.now(timezone.utc)
|
|
100
|
+
elif isinstance(timestamp, datetime):
|
|
101
|
+
dt = timestamp
|
|
102
|
+
if dt.tzinfo is None:
|
|
103
|
+
dt = dt.replace(tzinfo=timezone.utc)
|
|
104
|
+
elif isinstance(timestamp, str):
|
|
105
|
+
dt = datetime.fromisoformat(timestamp)
|
|
106
|
+
if dt.tzinfo is None:
|
|
107
|
+
dt = dt.replace(tzinfo=timezone.utc)
|
|
108
|
+
else:
|
|
109
|
+
raise ValueError(f"Unsupported timestamp type: {type(timestamp)}")
|
|
110
|
+
return int(dt.timestamp() * 1e9)
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def get_kt_install_url(freeze: bool = False):
|
|
114
|
+
# Returns:
|
|
115
|
+
# str: kubetorch install url
|
|
116
|
+
# bool: whether to install in editable mode
|
|
117
|
+
if kt_config.install_url or freeze:
|
|
118
|
+
return kt_config.install_url, False
|
|
119
|
+
local_kt_path = get_local_install_path("kubetorch")
|
|
120
|
+
if local_kt_path and (Path(local_kt_path) / "pyproject.toml").exists():
|
|
121
|
+
return local_kt_path, True
|
|
122
|
+
elif local_kt_path and local_kt_path.endswith(".whl"):
|
|
123
|
+
return local_kt_path, False
|
|
124
|
+
else:
|
|
125
|
+
import kubetorch as kt
|
|
126
|
+
|
|
127
|
+
version = kt.__version__
|
|
128
|
+
return version, False
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
class LogVerbosity(str, enum.Enum):
|
|
132
|
+
DEBUG = "debug"
|
|
133
|
+
INFO = "info"
|
|
134
|
+
CRITICAL = "critical"
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
####################################################################################################
|
|
138
|
+
# Logging redirection
|
|
139
|
+
####################################################################################################
|
|
140
|
+
class StreamTee(object):
|
|
141
|
+
def __init__(self, instream, outstreams):
|
|
142
|
+
self.instream = instream
|
|
143
|
+
self.outstreams = outstreams
|
|
144
|
+
|
|
145
|
+
def write(self, message):
|
|
146
|
+
self.instream.write(message)
|
|
147
|
+
for stream in self.outstreams:
|
|
148
|
+
if message:
|
|
149
|
+
stream.write(message)
|
|
150
|
+
# We flush here to ensure that the logs are written to the file immediately
|
|
151
|
+
# see https://github.com/run-house/runhouse/pull/724
|
|
152
|
+
stream.flush()
|
|
153
|
+
|
|
154
|
+
def writelines(self, lines):
|
|
155
|
+
self.instream.writelines(lines)
|
|
156
|
+
for stream in self.outstreams:
|
|
157
|
+
stream.writelines(lines)
|
|
158
|
+
stream.flush()
|
|
159
|
+
|
|
160
|
+
def flush(self):
|
|
161
|
+
self.instream.flush()
|
|
162
|
+
for stream in self.outstreams:
|
|
163
|
+
stream.flush()
|
|
164
|
+
|
|
165
|
+
def __getattr__(self, item):
|
|
166
|
+
# Needed in case someone calls a method on instream, such as Ray calling sys.stdout.istty()
|
|
167
|
+
return getattr(self.instream, item)
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
class capture_stdout:
|
|
171
|
+
"""Context manager for capturing stdout to a file, list, or stream, while still printing to stdout."""
|
|
172
|
+
|
|
173
|
+
def __init__(self, output=None):
|
|
174
|
+
self.output = output
|
|
175
|
+
self._stream = None
|
|
176
|
+
|
|
177
|
+
def __enter__(self):
|
|
178
|
+
if self.output is None:
|
|
179
|
+
self.output = StringIO()
|
|
180
|
+
|
|
181
|
+
if isinstance(self.output, str):
|
|
182
|
+
self._stream = open(self.output, "w")
|
|
183
|
+
else:
|
|
184
|
+
self._stream = self.output
|
|
185
|
+
sys.stdout = StreamTee(sys.stdout, [self])
|
|
186
|
+
sys.stderr = StreamTee(sys.stderr, [self])
|
|
187
|
+
return self
|
|
188
|
+
|
|
189
|
+
def write(self, message):
|
|
190
|
+
self._stream.write(message)
|
|
191
|
+
|
|
192
|
+
def flush(self):
|
|
193
|
+
self._stream.flush()
|
|
194
|
+
|
|
195
|
+
@property
|
|
196
|
+
def stream(self):
|
|
197
|
+
if isinstance(self.output, str):
|
|
198
|
+
return open(self.output, "r")
|
|
199
|
+
return self._stream
|
|
200
|
+
|
|
201
|
+
def list(self):
|
|
202
|
+
if isinstance(self.output, str):
|
|
203
|
+
return self.stream.readlines()
|
|
204
|
+
return (self.stream.getvalue() or "").splitlines()
|
|
205
|
+
|
|
206
|
+
def __str__(self):
|
|
207
|
+
return self.stream.getvalue()
|
|
208
|
+
|
|
209
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
210
|
+
if hasattr(sys.stdout, "instream"):
|
|
211
|
+
sys.stdout = sys.stdout.instream
|
|
212
|
+
if hasattr(sys.stderr, "instream"):
|
|
213
|
+
sys.stderr = sys.stderr.instream
|
|
214
|
+
self._stream.close()
|
|
215
|
+
return False
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
####################################################################################################
|
|
219
|
+
# Logging formatting
|
|
220
|
+
####################################################################################################
|
|
221
|
+
class ColoredFormatter:
|
|
222
|
+
COLORS = {
|
|
223
|
+
"black": "\u001b[30m",
|
|
224
|
+
"red": "\u001b[31m",
|
|
225
|
+
"green": "\u001b[32m",
|
|
226
|
+
"yellow": "\u001b[33m",
|
|
227
|
+
"blue": "\u001b[34m",
|
|
228
|
+
"magenta": "\u001b[35m",
|
|
229
|
+
"cyan": "\u001b[36m",
|
|
230
|
+
"white": "\u001b[37m",
|
|
231
|
+
"bold": "\u001b[1m",
|
|
232
|
+
"italic": "\u001b[3m",
|
|
233
|
+
"reset": "\u001b[0m",
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
@classmethod
|
|
237
|
+
def get_color(cls, color: str):
|
|
238
|
+
return cls.COLORS.get(color, "")
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
class ServerLogsFormatter:
|
|
242
|
+
def __init__(self, name: str = None):
|
|
243
|
+
self.name = name
|
|
244
|
+
self.start_color = ColoredFormatter.get_color("cyan")
|
|
245
|
+
self.reset_color = ColoredFormatter.get_color("reset")
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
def initialize_k8s_clients():
|
|
249
|
+
"""Initialize Kubernetes API clients."""
|
|
250
|
+
load_kubeconfig()
|
|
251
|
+
return (
|
|
252
|
+
client.CoreV1Api(),
|
|
253
|
+
client.CustomObjectsApi(),
|
|
254
|
+
client.AppsV1Api(),
|
|
255
|
+
)
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
def string_to_dict(value):
|
|
259
|
+
try:
|
|
260
|
+
result = json.loads(value or "{}")
|
|
261
|
+
return result if isinstance(result, dict) else {}
|
|
262
|
+
except (json.JSONDecodeError, TypeError):
|
|
263
|
+
return {}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: kubetorch
|
|
3
|
+
Version: 0.2.5
|
|
4
|
+
Summary: A Fast, Pythonic, 'Serverless' Interface for Running ML Workloads on Kubernetes
|
|
5
|
+
License: Apache 2.0
|
|
6
|
+
Author: Runhouse Team
|
|
7
|
+
Requires-Python: >=3.9,<=3.13
|
|
8
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
9
|
+
Classifier: License :: Other/Proprietary License
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
16
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
17
|
+
Classifier: Topic :: System :: Distributed Computing
|
|
18
|
+
Provides-Extra: client
|
|
19
|
+
Provides-Extra: docs
|
|
20
|
+
Provides-Extra: otel
|
|
21
|
+
Provides-Extra: server
|
|
22
|
+
Requires-Dist: fastapi ; extra == "server"
|
|
23
|
+
Requires-Dist: httpx (>=0.28.0,<0.29.0)
|
|
24
|
+
Requires-Dist: jinja2 (>=3.0)
|
|
25
|
+
Requires-Dist: kubernetes (>=20.0.0,!=32.0.0)
|
|
26
|
+
Requires-Dist: myst-parser ; extra == "docs"
|
|
27
|
+
Requires-Dist: opentelemetry-api ; extra == "otel"
|
|
28
|
+
Requires-Dist: opentelemetry-distro ; extra == "otel"
|
|
29
|
+
Requires-Dist: opentelemetry-exporter-otlp ; extra == "otel"
|
|
30
|
+
Requires-Dist: opentelemetry-exporter-prometheus ; extra == "otel"
|
|
31
|
+
Requires-Dist: opentelemetry-instrumentation ; extra == "otel"
|
|
32
|
+
Requires-Dist: opentelemetry-instrumentation-fastapi ; extra == "otel"
|
|
33
|
+
Requires-Dist: opentelemetry-instrumentation-logging ; extra == "otel"
|
|
34
|
+
Requires-Dist: opentelemetry-instrumentation-requests ; extra == "otel"
|
|
35
|
+
Requires-Dist: opentelemetry-sdk ; extra == "otel"
|
|
36
|
+
Requires-Dist: prometheus-client ; extra == "otel"
|
|
37
|
+
Requires-Dist: pydantic (>=2.5.0)
|
|
38
|
+
Requires-Dist: python-json-logger ; extra == "server"
|
|
39
|
+
Requires-Dist: pyyaml (>=6.0,<7.0)
|
|
40
|
+
Requires-Dist: requests (>=2.32.0,<3.0.0)
|
|
41
|
+
Requires-Dist: rich ; extra == "client"
|
|
42
|
+
Requires-Dist: sphinx ; extra == "docs"
|
|
43
|
+
Requires-Dist: sphinx-autodoc-typehints ; extra == "docs"
|
|
44
|
+
Requires-Dist: sphinx-book-theme ; extra == "docs"
|
|
45
|
+
Requires-Dist: typer ; extra == "client"
|
|
46
|
+
Requires-Dist: uvicorn[standard] ; extra == "server"
|
|
47
|
+
Requires-Dist: web-pdb ; extra == "server"
|
|
48
|
+
Requires-Dist: websockets (>=15.0,<16.0)
|
|
49
|
+
Project-URL: Documentation, https://www.run.house/kubetorch/introduction
|
|
50
|
+
Project-URL: Homepage, https://run.house
|
|
51
|
+
Project-URL: Repository, https://github.com/run-house/kubetorch
|
|
52
|
+
Description-Content-Type: text/markdown
|
|
53
|
+
|
|
54
|
+
# 📦Kubetorch🔥
|
|
55
|
+
|
|
56
|
+
**A Fast, Pythonic, "Serverless" Interface for Running ML Workloads on Kubernetes**
|
|
57
|
+
|
|
58
|
+
Kubetorch lets you programmatically build, iterate, and deploy ML applications on Kubernetes at any scale - directly from Python.
|
|
59
|
+
|
|
60
|
+
It brings your cluster's compute power into your local development environment, enabling extremely fast iteration (1-2 seconds). Logs, exceptions, and hardware faults are automatically propagated back to you in real-time.
|
|
61
|
+
|
|
62
|
+
Since Kubetorch has no local runtime or code serialization, you can access large-scale cluster compute from any Python environment - your IDE, notebooks, CI pipelines, or production code - just like you would use a local process pool.
|
|
63
|
+
|
|
64
|
+
## What Kubetorch Enables
|
|
65
|
+
|
|
66
|
+
- **100x faster iteration** from 10+ minutes to 1-3 seconds for complex ML applications like RL and distributed training
|
|
67
|
+
- **50%+ compute cost savings** through intelligent resource allocation, bin-packing, and dynamic scaling
|
|
68
|
+
- **95% fewer production faults** with built-in fault handling with programmatic error recovery and resource adjustment
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
[Apache 2.0 License](https://github.com/run-house/runhouse/blob/main/LICENSE)
|
|
73
|
+
|
|
74
|
+
**🏃♀️ Built by [Runhouse](https://www.run.house) 🏠**
|
|
75
|
+
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
kubetorch/__init__.py,sha256=KMAu8wmLI37eGl6N8GtU57IM_0NtGBuu0pZ7VmACC7s,2332
|
|
2
|
+
kubetorch/cli.py,sha256=bY9acXITiDRtm_W9f1J_39kApszb_1nsoKMoZWIClw4,70624
|
|
3
|
+
kubetorch/cli_utils.py,sha256=yz3tUpyEH7yJk3a3aWYPAx1qKd474FX78h27WNJ-Lds,32748
|
|
4
|
+
kubetorch/config.py,sha256=re88nQ0jumjkDhzf4UZQ2nJlAqt9rBF641KefNq07vc,16446
|
|
5
|
+
kubetorch/constants.py,sha256=gaMhdGbz9vFlmnSM0aGwoRBUtfPjlA2VDH-x2YPXNg0,346
|
|
6
|
+
kubetorch/docs/Makefile,sha256=ViKZxIiAhmNzDK14SzAubiaIrrEUA_rTxWxy8SZxywk,479
|
|
7
|
+
kubetorch/docs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
8
|
+
kubetorch/docs/_ext/json_globaltoc.py,sha256=LAX_EKskCdUI9bmAnCXfdyRTViwX1NulUXu_kATyKL4,1582
|
|
9
|
+
kubetorch/docs/api/cli.rst,sha256=_V2WVVODbbdcopWx-BLJkHiO_1BrBb9tKKvl4BTgrHw,400
|
|
10
|
+
kubetorch/docs/api/python/app.rst,sha256=TYXLcYbCEqVW7l1VQ9NVFcCl73tuJ9oPMAMcQ_sLzk4,492
|
|
11
|
+
kubetorch/docs/api/python/cls.rst,sha256=h5tjCqtyQNWtmBOaH5ERGS1nxp0Selm1fbsIMcnO-H8,398
|
|
12
|
+
kubetorch/docs/api/python/compute.rst,sha256=UyFehzcpMU4DszdSJna1w2Bq-ODWmK2Y9YmA6pDld2w,437
|
|
13
|
+
kubetorch/docs/api/python/config.rst,sha256=3-qphQwOo9lFK4balsmYD2t4hnPAVlZ72ASpu6mUxtI,278
|
|
14
|
+
kubetorch/docs/api/python/fn.rst,sha256=8IC4o2Acc4yP-HYGrRkNZcAgrQbnepyv77MAANV-ecQ,396
|
|
15
|
+
kubetorch/docs/api/python/image.rst,sha256=D_VKiEIr56ZUyxQR8SG2lRqq6JQYsYs_259_kyVQNak,314
|
|
16
|
+
kubetorch/docs/api/python/secret.rst,sha256=C6IdKjg2-p86zDzRPOTkYxScLs1D3zXrtQYh5Bnh9B4,339
|
|
17
|
+
kubetorch/docs/api/python/volumes.rst,sha256=D2DZUsjrH4rNB1a0tRV-t8P2HcHe4bG6DAMKKncab6g,330
|
|
18
|
+
kubetorch/docs/api/python.rst,sha256=cnqqGeEFASyJt0A--c9yAzadusgbPJWZP7SeQL6MeAM,2997
|
|
19
|
+
kubetorch/docs/conf.py,sha256=P7ZQWnIQYCn2aqXLeMlc6mG4aTzxXwcqqYwHm02ZCUI,1954
|
|
20
|
+
kubetorch/docs/index.rst,sha256=DAoVC-1NJQUStUlbq446cb1Iy_ae1CqdBIXUbC6mlYk,578
|
|
21
|
+
kubetorch/docs/requirements.txt,sha256=-NDXLpwXyEHQuep9rebi9OdjkRoewrGouhaccZDph4A,128
|
|
22
|
+
kubetorch/globals.py,sha256=mD_xHOiySbqvoBR7ZV7GG0ZIr0P-38hdhno4gSzhuks,9339
|
|
23
|
+
kubetorch/logger.py,sha256=uLcpdozhAVGV88_kiop6qI9mOFmCpZ8xJ5SyilHhYuw,1628
|
|
24
|
+
kubetorch/resources/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
25
|
+
kubetorch/resources/callables/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
26
|
+
kubetorch/resources/callables/cls/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
27
|
+
kubetorch/resources/callables/cls/cls.py,sha256=0DNm4ShPsuU4Eu4csTiuLeiXYpxEPIfGD6HZFiCiZsQ,5876
|
|
28
|
+
kubetorch/resources/callables/fn/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
29
|
+
kubetorch/resources/callables/fn/fn.py,sha256=7Oww23Y4AtMB7U6XDrtM9h9ZbAIpk1K1oSXIbFaSPqI,5096
|
|
30
|
+
kubetorch/resources/callables/module.py,sha256=1sofC4StF8fQIIkZa1FweWR_MOvyZolV2F3Xsx3C10s,54629
|
|
31
|
+
kubetorch/resources/callables/utils.py,sha256=c9QDnmh73-pYe-TzalatZ4Whe7nGFkm9HYbNCuUeYbU,8102
|
|
32
|
+
kubetorch/resources/compute/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
33
|
+
kubetorch/resources/compute/app.py,sha256=sSfkBsF0fsMOuoj8VBdJKEg3P6AMmmslIt8T58zCf-4,8494
|
|
34
|
+
kubetorch/resources/compute/compute.py,sha256=E-m3_KOzmByseO3gy3a_umsyAYGqQIhdqKyFK5PNwGs,98335
|
|
35
|
+
kubetorch/resources/compute/decorators.py,sha256=R2Zkx2qIr1-Cbgfffs4R8Qb63JmDJotLG8dDDIsSxIg,5031
|
|
36
|
+
kubetorch/resources/compute/utils.py,sha256=byzdWdYAYEieyaSp0-zF937UXr6VrRvrmYAI61Z-ktI,37118
|
|
37
|
+
kubetorch/resources/compute/websocket.py,sha256=6eECrP_vu-in9c0DnwX6cSshTL8Hj-N7c1G6oB-TQpA,4524
|
|
38
|
+
kubetorch/resources/images/__init__.py,sha256=JyEkhdAaBLjjO1iUkdKIZFBTTC-XpZ2z-Livr_cUUDM,36
|
|
39
|
+
kubetorch/resources/images/image.py,sha256=tD8KjpWCEMgwycfFqxDb189o0_OhFPn5zqKUzQM3trQ,16330
|
|
40
|
+
kubetorch/resources/images/images.py,sha256=hLpC6TMcjsBTWG_LtCG7odYRlqUOsXrOjuS8OpgtKD0,1779
|
|
41
|
+
kubetorch/resources/secrets/__init__.py,sha256=bAcntNq4IVdbgfL-NiUSMCJzskAvhuzD5tTUuXa75q4,90
|
|
42
|
+
kubetorch/resources/secrets/kubernetes_secrets_client.py,sha256=DDwqsrWWFdzVAIwX0cl1RhmfmanEYzDBsHsSRpwPJVM,15100
|
|
43
|
+
kubetorch/resources/secrets/provider_secrets/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
44
|
+
kubetorch/resources/secrets/provider_secrets/anthropic_secret.py,sha256=_vGgkTNFZIlIuMyD5TF_yIEaSFr2cGsH76_fLTD-O7E,301
|
|
45
|
+
kubetorch/resources/secrets/provider_secrets/aws_secret.py,sha256=UY8R_r-NvwTUTl_6_jLwKz6A_2nOACwueFK2cj0X99g,410
|
|
46
|
+
kubetorch/resources/secrets/provider_secrets/azure_secret.py,sha256=VEn8DLThps2GYF2W6C0xtn6qNnCS4S6aFmdVwkTY7W0,417
|
|
47
|
+
kubetorch/resources/secrets/provider_secrets/cohere_secret.py,sha256=XdztDQLSZKQf9r76V_h9IJPCGl5Y3DdJJVObvByp9hk,286
|
|
48
|
+
kubetorch/resources/secrets/provider_secrets/gcp_secret.py,sha256=JsdAGspPDOtsuWv1-_SIsFvxc7x0saz97xNBVNuV2JQ,420
|
|
49
|
+
kubetorch/resources/secrets/provider_secrets/github_secret.py,sha256=ZqGBn4_YFBdhOG2qa2VSJFn3wEeaka8mbfRvOrDOt-Q,342
|
|
50
|
+
kubetorch/resources/secrets/provider_secrets/huggingface_secret.py,sha256=2E8JIohrzJJaLW1p5Mm2yv-Dpb4iqS93CmTQGn86H9k,536
|
|
51
|
+
kubetorch/resources/secrets/provider_secrets/kubeconfig_secret.py,sha256=4d8OB429AX2tdDhEvswHE-tuEAf4dj4XptYBTkkUxCU,298
|
|
52
|
+
kubetorch/resources/secrets/provider_secrets/lambda_secret.py,sha256=0WQQy8c6Dhxk8APT1RMXOskak2j-5hDsQjN7vn3fAkE,340
|
|
53
|
+
kubetorch/resources/secrets/provider_secrets/langchain_secret.py,sha256=uhjO8X9WKxhfzVa3Y2lQxNd-rAqYsArE7ErXAj9A6Hg,301
|
|
54
|
+
kubetorch/resources/secrets/provider_secrets/openai_secret.py,sha256=rqlO2IQUmdQ7MkqHbqCWoWVsodxjyA4A_B97qNv8Pf4,274
|
|
55
|
+
kubetorch/resources/secrets/provider_secrets/pinecone_secret.py,sha256=HeXyVUkS5wB-rIouDsQNP2kYJcaH0qkz06SGFg13kSA,296
|
|
56
|
+
kubetorch/resources/secrets/provider_secrets/providers.py,sha256=5doBdFwDSrj5TIXpXntPU6WIXOxscDsxwljKW58HcJI,3163
|
|
57
|
+
kubetorch/resources/secrets/provider_secrets/ssh_secret.py,sha256=rZjuiEhZ7isg9ZfgkIg9frBqY4DUEZBMjwE0hv7pYxI,272
|
|
58
|
+
kubetorch/resources/secrets/provider_secrets/wandb_secret.py,sha256=eVfCtMejPb7fvt5Yz1PJV7oXRBrkt-ialj3fo_5nOjI,269
|
|
59
|
+
kubetorch/resources/secrets/secret.py,sha256=gpPMVq8kOB6kRiNXxOCM9gbWxf186ZRGI2gK4PifCQA,9226
|
|
60
|
+
kubetorch/resources/secrets/secret_factory.py,sha256=4GdHYx5hB7X2xdDd7vVGeJqBVMVMZccgRgPSFBhTZ9s,2890
|
|
61
|
+
kubetorch/resources/secrets/utils.py,sha256=2MWE8ItzTWS2GIvrmFhOlXhyQ0IyPrZ0Ghs594rDtZA,7862
|
|
62
|
+
kubetorch/resources/volumes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
63
|
+
kubetorch/resources/volumes/volume.py,sha256=JYs-4gVz0gNuv0F_1pSeQEKEal6devzwHEIwqE6k4V0,11766
|
|
64
|
+
kubetorch/servers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
65
|
+
kubetorch/servers/http/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
66
|
+
kubetorch/servers/http/distributed_utils.py,sha256=YA5FnfojzZ3DqkGe6nHQEz1fOXnAPrSCMSdTDzTcFOQ,125200
|
|
67
|
+
kubetorch/servers/http/http_client.py,sha256=kZ0hGSMxuqszJ-rspBQfT5LwU3B26E61Fa7aMvmpio8,34626
|
|
68
|
+
kubetorch/servers/http/http_server.py,sha256=7bLHaDa3FF2TuyhCRzx45aL4r-xO0j9BRzbKWLfPJPc,65556
|
|
69
|
+
kubetorch/servers/http/server_metrics.py,sha256=2mMbvaUEmo2-VwsJhCEqXmNS-0H_i6AWBcLwMQDVil4,9298
|
|
70
|
+
kubetorch/servers/http/utils.py,sha256=63l4ybkEyEzsZwKsmFJwFjiFNdoCgPFMJu3QE0QAvi4,28174
|
|
71
|
+
kubetorch/serving/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
72
|
+
kubetorch/serving/autoscaling.py,sha256=KkXVqo2BnofJ9vsHXcPGgBxiIIrFHyjE-AnhozuVq-Q,6228
|
|
73
|
+
kubetorch/serving/base_service_manager.py,sha256=4ZuPymFyjL6TptUfGmljkqq11PwTuNq-D_WpSHnEPDU,13151
|
|
74
|
+
kubetorch/serving/constants.py,sha256=UZfp57exU3YABO9NN93AYrzEhJWaJQ4i9orvEyIEQKY,2287
|
|
75
|
+
kubetorch/serving/deployment_service_manager.py,sha256=gY4ggtR-GCec3ADKAj0RS4OMh9euYLahcMVboL6t2GA,17399
|
|
76
|
+
kubetorch/serving/knative_service_manager.py,sha256=2F18pnjQ4Vi-ygWaMIWbHpaTFgujwjMyVieve9h7Pu0,19790
|
|
77
|
+
kubetorch/serving/raycluster_service_manager.py,sha256=jg-FzYZjYgUU-8clPyVH_qkDDqJ8IMg9HRwgGROfr9A,22013
|
|
78
|
+
kubetorch/serving/service_manager.py,sha256=4LdrzfwPFPf7IsSwR7HVxuSrbyBNw1dI4xPHR8TECrw,720
|
|
79
|
+
kubetorch/serving/templates/deployment_template.yaml,sha256=_hPm7sXCb2BVeYuhyAGz-hRzjAoSaXNikJj_3MJfLsM,435
|
|
80
|
+
kubetorch/serving/templates/knative_service_template.yaml,sha256=yKxBdduIOqDntywBdUFVaV3hc50cZhl6K91FNok6X_U,553
|
|
81
|
+
kubetorch/serving/templates/kt_setup_template.sh.j2,sha256=wPJi6nTG22gcCNyck4ewGjpyhAQMScXDi2dRlKZSfvA,3047
|
|
82
|
+
kubetorch/serving/templates/pod_template.yaml,sha256=Dao0aUrPQAfy7ZwlV_IguCGizBKYQvlrjOrGsJxBVd8,5651
|
|
83
|
+
kubetorch/serving/templates/raycluster_service_template.yaml,sha256=kW_bIJu36Ud4kI8Q9ycnQfIIbhkxNa-C6OP93Jpl-EA,1037
|
|
84
|
+
kubetorch/serving/templates/raycluster_template.yaml,sha256=ruWFk09-E85WZJc64l7NXrsdGYcW4spPzErWuzrLLes,990
|
|
85
|
+
kubetorch/serving/templates/service_template.yaml,sha256=ClIMlW-JzK4I6YWo9oBbwYXgNTcz8AGDMpo8_Q8C4ng,642
|
|
86
|
+
kubetorch/serving/templates/workerset_template.yaml,sha256=l7svttZrQPHDbZuZsO8EmG38eVlFUDr_UyP3E2Ci0zY,981
|
|
87
|
+
kubetorch/serving/utils.py,sha256=1-cmhTqvMv73vwtoNkgWu0_Auo9y4ka-91-G2bXWm0I,12172
|
|
88
|
+
kubetorch/utils.py,sha256=Ae4FBtEgZ4_0xDUTuknOcwP7vnAwvqv8jI6zrHPA7i4,8656
|
|
89
|
+
kubetorch-0.2.5.dist-info/METADATA,sha256=YdgX_7EH63e9vpkSSAap7cxj9CdFExChcuBiyf6P4CE,3631
|
|
90
|
+
kubetorch-0.2.5.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
|
|
91
|
+
kubetorch-0.2.5.dist-info/entry_points.txt,sha256=Gkg5B9pHJpGf-Zxk1LGx7RIG_9EI04MAbD6m4l1Rx3U,107
|
|
92
|
+
kubetorch-0.2.5.dist-info/RECORD,,
|