kubetorch 0.2.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 kubetorch might be problematic. Click here for more details.

Files changed (93) hide show
  1. kubetorch/__init__.py +60 -0
  2. kubetorch/cli.py +1985 -0
  3. kubetorch/cli_utils.py +1025 -0
  4. kubetorch/config.py +453 -0
  5. kubetorch/constants.py +18 -0
  6. kubetorch/docs/Makefile +18 -0
  7. kubetorch/docs/__init__.py +0 -0
  8. kubetorch/docs/_ext/json_globaltoc.py +42 -0
  9. kubetorch/docs/api/cli.rst +10 -0
  10. kubetorch/docs/api/python/app.rst +21 -0
  11. kubetorch/docs/api/python/cls.rst +19 -0
  12. kubetorch/docs/api/python/compute.rst +25 -0
  13. kubetorch/docs/api/python/config.rst +11 -0
  14. kubetorch/docs/api/python/fn.rst +19 -0
  15. kubetorch/docs/api/python/image.rst +14 -0
  16. kubetorch/docs/api/python/secret.rst +18 -0
  17. kubetorch/docs/api/python/volumes.rst +13 -0
  18. kubetorch/docs/api/python.rst +101 -0
  19. kubetorch/docs/conf.py +69 -0
  20. kubetorch/docs/index.rst +20 -0
  21. kubetorch/docs/requirements.txt +5 -0
  22. kubetorch/globals.py +285 -0
  23. kubetorch/logger.py +59 -0
  24. kubetorch/resources/__init__.py +0 -0
  25. kubetorch/resources/callables/__init__.py +0 -0
  26. kubetorch/resources/callables/cls/__init__.py +0 -0
  27. kubetorch/resources/callables/cls/cls.py +157 -0
  28. kubetorch/resources/callables/fn/__init__.py +0 -0
  29. kubetorch/resources/callables/fn/fn.py +133 -0
  30. kubetorch/resources/callables/module.py +1416 -0
  31. kubetorch/resources/callables/utils.py +174 -0
  32. kubetorch/resources/compute/__init__.py +0 -0
  33. kubetorch/resources/compute/app.py +261 -0
  34. kubetorch/resources/compute/compute.py +2596 -0
  35. kubetorch/resources/compute/decorators.py +139 -0
  36. kubetorch/resources/compute/rbac.py +74 -0
  37. kubetorch/resources/compute/utils.py +1114 -0
  38. kubetorch/resources/compute/websocket.py +137 -0
  39. kubetorch/resources/images/__init__.py +1 -0
  40. kubetorch/resources/images/image.py +414 -0
  41. kubetorch/resources/images/images.py +74 -0
  42. kubetorch/resources/secrets/__init__.py +2 -0
  43. kubetorch/resources/secrets/kubernetes_secrets_client.py +412 -0
  44. kubetorch/resources/secrets/provider_secrets/__init__.py +0 -0
  45. kubetorch/resources/secrets/provider_secrets/anthropic_secret.py +12 -0
  46. kubetorch/resources/secrets/provider_secrets/aws_secret.py +16 -0
  47. kubetorch/resources/secrets/provider_secrets/azure_secret.py +14 -0
  48. kubetorch/resources/secrets/provider_secrets/cohere_secret.py +12 -0
  49. kubetorch/resources/secrets/provider_secrets/gcp_secret.py +16 -0
  50. kubetorch/resources/secrets/provider_secrets/github_secret.py +13 -0
  51. kubetorch/resources/secrets/provider_secrets/huggingface_secret.py +20 -0
  52. kubetorch/resources/secrets/provider_secrets/kubeconfig_secret.py +12 -0
  53. kubetorch/resources/secrets/provider_secrets/lambda_secret.py +13 -0
  54. kubetorch/resources/secrets/provider_secrets/langchain_secret.py +12 -0
  55. kubetorch/resources/secrets/provider_secrets/openai_secret.py +11 -0
  56. kubetorch/resources/secrets/provider_secrets/pinecone_secret.py +12 -0
  57. kubetorch/resources/secrets/provider_secrets/providers.py +93 -0
  58. kubetorch/resources/secrets/provider_secrets/ssh_secret.py +12 -0
  59. kubetorch/resources/secrets/provider_secrets/wandb_secret.py +11 -0
  60. kubetorch/resources/secrets/secret.py +238 -0
  61. kubetorch/resources/secrets/secret_factory.py +70 -0
  62. kubetorch/resources/secrets/utils.py +209 -0
  63. kubetorch/resources/volumes/__init__.py +0 -0
  64. kubetorch/resources/volumes/volume.py +365 -0
  65. kubetorch/servers/__init__.py +0 -0
  66. kubetorch/servers/http/__init__.py +0 -0
  67. kubetorch/servers/http/distributed_utils.py +3223 -0
  68. kubetorch/servers/http/http_client.py +730 -0
  69. kubetorch/servers/http/http_server.py +1788 -0
  70. kubetorch/servers/http/server_metrics.py +278 -0
  71. kubetorch/servers/http/utils.py +728 -0
  72. kubetorch/serving/__init__.py +0 -0
  73. kubetorch/serving/autoscaling.py +173 -0
  74. kubetorch/serving/base_service_manager.py +363 -0
  75. kubetorch/serving/constants.py +83 -0
  76. kubetorch/serving/deployment_service_manager.py +478 -0
  77. kubetorch/serving/knative_service_manager.py +519 -0
  78. kubetorch/serving/raycluster_service_manager.py +582 -0
  79. kubetorch/serving/service_manager.py +18 -0
  80. kubetorch/serving/templates/deployment_template.yaml +17 -0
  81. kubetorch/serving/templates/knative_service_template.yaml +19 -0
  82. kubetorch/serving/templates/kt_setup_template.sh.j2 +81 -0
  83. kubetorch/serving/templates/pod_template.yaml +194 -0
  84. kubetorch/serving/templates/raycluster_service_template.yaml +42 -0
  85. kubetorch/serving/templates/raycluster_template.yaml +35 -0
  86. kubetorch/serving/templates/service_template.yaml +21 -0
  87. kubetorch/serving/templates/workerset_template.yaml +36 -0
  88. kubetorch/serving/utils.py +377 -0
  89. kubetorch/utils.py +284 -0
  90. kubetorch-0.2.0.dist-info/METADATA +121 -0
  91. kubetorch-0.2.0.dist-info/RECORD +93 -0
  92. kubetorch-0.2.0.dist-info/WHEEL +4 -0
  93. kubetorch-0.2.0.dist-info/entry_points.txt +5 -0
kubetorch/config.py ADDED
@@ -0,0 +1,453 @@
1
+ import os
2
+ from functools import cached_property
3
+ from pathlib import Path
4
+
5
+ import yaml
6
+
7
+ from kubetorch.logger import get_logger
8
+
9
+
10
+ logger = get_logger(__name__)
11
+
12
+
13
+ ENV_MAPPINGS = {
14
+ "username": "KT_USERNAME",
15
+ "license_key": "KT_LICENSE_KEY",
16
+ "namespace": "KT_NAMESPACE",
17
+ "install_namespace": "KT_INSTALL_NAMESPACE",
18
+ "install_url": "KT_INSTALL_URL",
19
+ "stream_logs": "KT_STREAM_LOGS",
20
+ "log_verbosity": "KT_LOG_VERBOSITY",
21
+ "queue": "KT_QUEUE",
22
+ "tracing_enabled": "KT_TRACING_ENABLED",
23
+ "volumes": "KT_VOLUMES",
24
+ "api_url": "KT_API_URL",
25
+ "cluster_config": "KT_CLUSTER_CONFIG",
26
+ }
27
+
28
+ DEFAULT_INSTALL_NAMESPACE = "kubetorch"
29
+
30
+
31
+ class KubetorchConfig:
32
+ CONFIG_FILE = Path("~/.kt/config.yaml")
33
+
34
+ def __init__(self):
35
+ self._api_url = None
36
+ self._cluster_config = None
37
+ self._install_namespace = None
38
+ self._install_url = None
39
+ self._license_key = None
40
+ self._log_verbosity = None
41
+ self._namespace = None
42
+ self._queue = None
43
+ self._stream_logs = None
44
+ self._tracing_enabled = None
45
+ self._username = None
46
+ self._volumes = None
47
+
48
+ @cached_property
49
+ def file_cache(self):
50
+ return self._load_from_file()
51
+
52
+ @cached_property
53
+ def current_context(self):
54
+ try:
55
+ from kubetorch.servers.http.utils import is_running_in_kubernetes
56
+
57
+ if is_running_in_kubernetes():
58
+ try:
59
+ with open(
60
+ "/var/run/secrets/kubernetes.io/serviceaccount/namespace"
61
+ ) as f:
62
+ return f.read().strip()
63
+ except FileNotFoundError:
64
+ return "default"
65
+
66
+ else:
67
+ from kubernetes import config
68
+
69
+ from kubetorch.utils import load_kubeconfig
70
+
71
+ load_kubeconfig()
72
+ _, active_context = config.list_kube_config_contexts()
73
+ return active_context.get("context", {}).get("namespace", "default")
74
+
75
+ except Exception:
76
+ return "default"
77
+
78
+ @property
79
+ def username(self):
80
+ """Username to use for Kubetorch deployments.
81
+
82
+ Used for authentication and resource naming. Will be validated to ensure Kubernetes compatibility.
83
+ """
84
+ if not self._username:
85
+ if self._get_env_var("username"):
86
+ self._username = self._get_env_var("username")
87
+ else:
88
+ self._username = self.file_cache.get("username")
89
+ return self._username
90
+
91
+ @username.setter
92
+ def username(self, value):
93
+ """Set kubetorch username for current process."""
94
+ from kubetorch.utils import validate_username
95
+
96
+ validated = validate_username(value)
97
+ if validated != value:
98
+ logger.info(
99
+ f"Username was validated and changed to {validated} to be Kubernetes-compatible."
100
+ )
101
+ self._username = validated
102
+
103
+ @property
104
+ def license_key(self):
105
+ """License key for authentication and billing.
106
+
107
+ Required for usage reporting and cluster authentication.
108
+ Can be found in the `basic install guide <https://www.run.house/kubetorch/installation>`_.
109
+ """
110
+ if not self._license_key:
111
+ if self._get_env_var("license_key"):
112
+ self._license_key = self._get_env_var("license_key")
113
+ else:
114
+ self._license_key = self.file_cache.get("license_key")
115
+ return self._license_key
116
+
117
+ @license_key.setter
118
+ def license_key(self, value: str):
119
+ """Set kubetorch license key for current process."""
120
+ self._license_key = value
121
+
122
+ @property
123
+ def queue(self):
124
+ """Default queue name for scheduling services.
125
+
126
+ Controls how cluster resources are allocated and prioritized for services.
127
+ See `scheduling and queues <https://www.run.house/kubetorch/advanced-installation#scheduling-and-queues>`_ for more info.
128
+ """
129
+ if not self._queue:
130
+ if self._get_env_var("queue"):
131
+ self._queue = self._get_env_var("queue")
132
+ else:
133
+ self._queue = self.file_cache.get("queue")
134
+ return self._queue
135
+
136
+ @queue.setter
137
+ def queue(self, value: str):
138
+ self._queue = value
139
+
140
+ @property
141
+ def volumes(self):
142
+ if not self._volumes:
143
+ if self._get_env_var("volumes"):
144
+ self._volumes = self._get_env_var("volumes")
145
+ else:
146
+ self._volumes = self.file_cache.get("volumes")
147
+ return self._volumes
148
+
149
+ @volumes.setter
150
+ def volumes(self, values):
151
+ if values is None or values == "None":
152
+ self._volumes = None
153
+ elif isinstance(values, str):
154
+ # Handle comma-separated string
155
+ self._volumes = [v.strip() for v in values.split(",") if v.strip()]
156
+ elif isinstance(values, list):
157
+ self._volumes = values
158
+ else:
159
+ raise ValueError(
160
+ "volumes must be a list of strings or comma-separated string"
161
+ )
162
+
163
+ @property
164
+ def api_url(self):
165
+ if not self._api_url:
166
+ if self._get_env_var("api_url"):
167
+ self._api_url = self._get_env_var("api_url")
168
+ else:
169
+ self._api_url = self.file_cache.get("api_url")
170
+ return self._api_url
171
+
172
+ @api_url.setter
173
+ def api_url(self, value: str):
174
+ self._api_url = value
175
+
176
+ @property
177
+ def namespace(self):
178
+ """Default Kubernetes namespace for Kubetorch deployments.
179
+
180
+ All services will be deployed to this namespace unless overridden in the
181
+ Compute resource constructor. If `install_namespace` is set, it will override this namespace.
182
+
183
+ Priority:
184
+ 1. Explicit override
185
+ 2. Environment variable
186
+ 3. File cache
187
+ 4. In-cluster namespace or kubeconfig current context
188
+ """
189
+ if (
190
+ self.install_namespace
191
+ and self.install_namespace != DEFAULT_INSTALL_NAMESPACE
192
+ ):
193
+ self._namespace = self.install_namespace
194
+ elif self._namespace is None:
195
+ ns = self._get_env_var("namespace") or self.file_cache.get("namespace")
196
+ self._namespace = ns or self.current_context
197
+ return self._namespace
198
+
199
+ @namespace.setter
200
+ def namespace(self, value):
201
+ """Set namespace for current process."""
202
+ self._namespace = value
203
+
204
+ @property
205
+ def install_namespace(self):
206
+ """Namespace for Kubetorch installation. Used for Kubetorch Cloud clients.
207
+
208
+ Priority:
209
+ 1. Explicit override
210
+ 2. Environment variable
211
+ 3. File cache
212
+ 4. Default install namespace
213
+ """
214
+ if self._install_namespace is None:
215
+ ns = self._get_env_var("install_namespace") or self.file_cache.get(
216
+ "install_namespace"
217
+ )
218
+ self._install_namespace = ns or DEFAULT_INSTALL_NAMESPACE
219
+ return self._install_namespace
220
+
221
+ @install_namespace.setter
222
+ def install_namespace(self, value):
223
+ """Set installnamespace for current process."""
224
+ self._install_namespace = value
225
+
226
+ @property
227
+ def install_url(self):
228
+ """URL of the Kubetorch version to install.
229
+
230
+ Used when installing Kubetorch in a Docker image or remote environment.
231
+ Can be found in the `basic install guide <https://www.run.house/kubetorch/installation>`_.
232
+ """
233
+ if self._install_url is None:
234
+ if self._get_env_var("install_url"):
235
+ self._install_url = self._get_env_var("install_url")
236
+ else:
237
+ self._install_url = self.file_cache.get("install_url")
238
+ return self._install_url
239
+
240
+ @install_url.setter
241
+ def install_url(self, value):
242
+ """Set default kubetorch install url in current process."""
243
+ self._install_url = value
244
+
245
+ @property
246
+ def log_verbosity(self):
247
+ """Verbosity of logs streamed from a remote deployment.
248
+ Log levels include ``debug``, ``info``, and ``critical``. Default is ``info``.
249
+
250
+ Note:
251
+ Only relevant when ``stream_logs`` is set to ``true``.
252
+ """
253
+ from kubetorch.utils import LogVerbosity
254
+
255
+ default_verbosity = LogVerbosity.INFO.value
256
+
257
+ if self._log_verbosity is None:
258
+ verbosity_env_var = self._get_env_var("log_verbosity")
259
+ if verbosity_env_var:
260
+ try:
261
+ verbosity_env_var = LogVerbosity(verbosity_env_var).value
262
+ except ValueError:
263
+ verbosity_env_var = default_verbosity
264
+
265
+ self._log_verbosity = verbosity_env_var
266
+ else:
267
+ self._log_verbosity = self.file_cache.get(
268
+ "log_verbosity", default_verbosity
269
+ )
270
+
271
+ return self._log_verbosity
272
+
273
+ @log_verbosity.setter
274
+ def log_verbosity(self, value):
275
+ """Set log verbosity."""
276
+ from kubetorch.utils import LogVerbosity
277
+
278
+ try:
279
+ # In case we are unsetting log_verbosity, None is a valid value
280
+ verbosity = LogVerbosity(value).value if value else None
281
+ except ValueError:
282
+ raise ValueError(
283
+ "Invalid log verbosity value. Must be one of: 'debug', 'info', 'critical'."
284
+ )
285
+
286
+ self._log_verbosity = verbosity
287
+
288
+ @property
289
+ def stream_logs(self):
290
+ """Whether to stream logs for Kubetorch services.
291
+
292
+ When enabled, logs from remote services are streamed back to your local environment
293
+ in real-time. Verbosity of the streamed logs can be controlled with ``log_verbosity``. Default is ``True``.
294
+
295
+ Note:
296
+ Requires `log streaming <https://www.run.house/kubetorch/advanced-installation#log-streaming>`_
297
+ to be configured in your cluster.
298
+ """
299
+ if self._stream_logs is None:
300
+ if self._get_env_var("stream_logs"):
301
+ self._stream_logs = self._get_env_var("stream_logs").lower() == "true"
302
+ else:
303
+ self._stream_logs = self.file_cache.get(
304
+ "stream_logs", True
305
+ ) # Default to True
306
+ return self._stream_logs
307
+
308
+ @stream_logs.setter
309
+ def stream_logs(self, value):
310
+ """Set log streaming for current process."""
311
+ from kubetorch.serving.utils import check_loki_enabled
312
+
313
+ bool_value = value
314
+
315
+ if not isinstance(value, bool):
316
+ if value is None:
317
+ pass # case we are unsetting stream_logs, so None is a valid value
318
+ elif isinstance(value, str) and value.lower() in ["true", "false"]:
319
+ bool_value = value.lower() == "true"
320
+ else:
321
+ raise ValueError("stream_logs must be a boolean value")
322
+ if bool_value:
323
+ # Check if the cluster has loki enabled
324
+ if not check_loki_enabled():
325
+ raise ValueError("Loki is not enabled in the cluster")
326
+ self._stream_logs = bool_value
327
+
328
+ @property
329
+ def tracing_enabled(self):
330
+ """Whether to enable distributed tracing for services.
331
+
332
+ When enabled, provides detailed trace information for debugging and monitoring Kubetorch deployments.
333
+ Default is ``False``.
334
+
335
+ Note:
336
+ Requires telemetry stack to be configured. See
337
+ `traces <https://www.run.house/kubetorch/advanced-installation#traces>`_ for more info.
338
+ """
339
+ if self._tracing_enabled is None:
340
+ if self._get_env_var("tracing_enabled"):
341
+ self._tracing_enabled = (
342
+ self._get_env_var("tracing_enabled").lower() == "true"
343
+ )
344
+ else:
345
+ self._tracing_enabled = self.file_cache.get(
346
+ "tracing_enabled", False
347
+ ) # Default to False - flip to true successfully only if configured
348
+ return self._tracing_enabled
349
+
350
+ @tracing_enabled.setter
351
+ def tracing_enabled(self, value):
352
+ """Set tracing collection."""
353
+ from kubetorch.serving.utils import check_tempo_enabled
354
+
355
+ bool_value = value
356
+
357
+ if not isinstance(value, bool):
358
+ if value is None:
359
+ pass # case we are unsetting tracing_enabled, so None is a valid value
360
+ elif isinstance(value, str) and value.lower() in ["true", "false"]:
361
+ bool_value = value.lower() == "true"
362
+ else:
363
+ raise ValueError("tracing_enabled must be a boolean value")
364
+ if bool_value:
365
+ # Check if the cluster has tempo enabled
366
+ if not check_tempo_enabled():
367
+ raise ValueError(
368
+ "Open telemetry collector and Tempo distributor not found on the cluster. "
369
+ "See https://www.run.house/kubetorch/advanced-installation for more info."
370
+ )
371
+ self._tracing_enabled = bool_value
372
+
373
+ @property
374
+ def cluster_config(self):
375
+ """Cluster Config.
376
+ Default is ``{}``.
377
+ """
378
+ from kubetorch.utils import string_to_dict
379
+
380
+ config = self._cluster_config
381
+ if self._cluster_config is None:
382
+ config = string_to_dict(self._get_env_var("cluster_config") or "")
383
+ if not config:
384
+ config = string_to_dict(self.file_cache.get("cluster_config", "{}"))
385
+ self._cluster_config = config
386
+ return config
387
+
388
+ @cluster_config.setter
389
+ def cluster_config(self, value):
390
+ """Set Cluster Config."""
391
+ from kubetorch.utils import string_to_dict
392
+
393
+ new_value = value
394
+ if not isinstance(new_value, dict):
395
+ if isinstance(new_value, str):
396
+ new_value = string_to_dict(new_value)
397
+ else:
398
+ new_value = {} # Default to empty dict
399
+ self._cluster_config = new_value
400
+
401
+ def __iter__(self):
402
+ for key in ENV_MAPPINGS:
403
+ value = getattr(self, key)
404
+ if value == "None":
405
+ value = None
406
+ yield key, value
407
+
408
+ def set(self, key, value):
409
+ if key not in ENV_MAPPINGS:
410
+ raise ValueError(f"Unknown config key: {key}")
411
+ setattr(self, key, value)
412
+ # if key is 'username' and value is None (unsetting username), we'll get the cached username,and not the
413
+ # new value
414
+ new_value = value if value is None else getattr(self, key)
415
+ return new_value
416
+
417
+ def get(self, key):
418
+ if key not in ENV_MAPPINGS:
419
+ raise ValueError(f"Unknown config key: {key}")
420
+ return getattr(self, key)
421
+
422
+ def write(self, user_values: dict = None):
423
+ """Write out config to local ``~/.kt/config.yaml``, to be used globally."""
424
+ # Ensure directory exists
425
+ self.CONFIG_FILE.expanduser().parent.mkdir(parents=True, exist_ok=True)
426
+ values = {
427
+ k: str(v) if isinstance(v, dict) else v
428
+ for k, v in dict(self).items()
429
+ if v is not None
430
+ }
431
+ if user_values:
432
+ values.update(user_values)
433
+
434
+ # Write to file
435
+ with self.CONFIG_FILE.expanduser().open("w") as stream:
436
+ yaml.safe_dump(values, stream)
437
+
438
+ def _get_env_var(self, key):
439
+ return os.getenv(ENV_MAPPINGS[key])
440
+
441
+ def _get_config_env_vars(self):
442
+ """Get config values as environment variables with proper KT_ prefixes."""
443
+ env_vars = {}
444
+ for key, value in dict(self).items():
445
+ if value is not None and key in ENV_MAPPINGS:
446
+ env_vars[ENV_MAPPINGS[key]] = value
447
+ return env_vars
448
+
449
+ def _load_from_file(self):
450
+ if self.CONFIG_FILE.expanduser().exists():
451
+ with open(self.CONFIG_FILE.expanduser(), "r") as stream:
452
+ return yaml.safe_load(stream) or {}
453
+ return {}
kubetorch/constants.py ADDED
@@ -0,0 +1,18 @@
1
+ LOCALHOST: str = "127.0.0.1"
2
+ DEFAULT_THANOS_PORT = 10902
3
+ DEFAULT_KUBECONFIG_PATH = "~/.kube/config"
4
+ MAX_PORT_TRIES = 10
5
+
6
+ # CLI constants
7
+ DOUBLE_SPACE_UNICODE = "\u00A0\u00A0"
8
+ BULLET_UNICODE = "\u2022"
9
+ DEFAULT_TAIL_LENGTH = 100 # log tail length
10
+
11
+ MAX_USERNAME_LENGTH = 16
12
+ MAX_K8S_NAME_LENGTH = 63
13
+
14
+ CPU_RATE = 0.01
15
+ GPU_RATE = 0.05
16
+
17
+ KT_MOUNT_FOLDER = "ktfs"
18
+ DEFAULT_VOLUME_ACCESS_MODE = "ReadWriteMany"
@@ -0,0 +1,18 @@
1
+ # Makefile for Sphinx documentation
2
+
3
+ # You can override these from the command line:
4
+ SPHINXBUILD ?= sphinx-build
5
+ SPHINXOPTS ?=
6
+ SOURCEDIR = .
7
+ BUILDDIR = _build
8
+
9
+ # Default target
10
+ help:
11
+ @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS)
12
+
13
+ json:
14
+ @$(SPHINXBUILD) -M json "$(SOURCEDIR)" "$(BUILDDIR)" -b json -t json
15
+
16
+ # Catch-all: route targets like `make html`, `make latexpdf`, etc.
17
+ %:
18
+ @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS)
File without changes
@@ -0,0 +1,42 @@
1
+ from typing import Any, Dict
2
+
3
+ from sphinx.application import Sphinx
4
+ from sphinx.environment.adapters.toctree import TocTree
5
+ from sphinxcontrib.serializinghtml import JSONHTMLBuilder
6
+
7
+ __version__ = "0.0.1"
8
+
9
+
10
+ def setup(app: Sphinx) -> Dict[str, Any]:
11
+ app.add_builder(SphinxGlobalTOCJSONHTMLBuilder, override=True)
12
+
13
+ return {"version": __version__, "parallel_read_safe": True}
14
+
15
+
16
+ class SphinxGlobalTOCJSONHTMLBuilder(JSONHTMLBuilder):
17
+
18
+ name: str = "json"
19
+
20
+ def get_doc_context(self, docname: str, body: str, metatags: str) -> Dict[str, Any]:
21
+ """
22
+ Extends :py:class:`sphinxcontrib.serializinghtml.JSONHTMLBuilder`.
23
+
24
+ Add a ``globaltoc`` key to our document that contains the HTML for the
25
+ global table of contents.
26
+
27
+ Note:
28
+
29
+ We're rendering the **full global toc** for the entire documentation
30
+ set into every page. We do this to easily render the toc on each
31
+ page and allow for a unique toc for each branch and repo version.
32
+ """
33
+ doc = super().get_doc_context(docname, body, metatags)
34
+ # Get the entire doctree. It is the 3rd argument (``collapse``) that
35
+ # does this. If you set that to ``True`` you will only get the submenu
36
+ # HTML included if you are on a page that is within that submenu.
37
+ self_toctree = TocTree(self.env).get_toctree_for(
38
+ "index", self, False, titles_only=True, includehidden=False, maxdepth=2
39
+ )
40
+ toctree = self.render_partial(self_toctree)["fragment"]
41
+ doc["globaltoc"] = toctree
42
+ return doc
@@ -0,0 +1,10 @@
1
+ Command Line Interface
2
+ ----------------------
3
+
4
+ Kubetorch offers a rich set of commands to offer you insight into running workloads at the individual and cluster level.
5
+ For more details on the inputs, you can run ``kt <method> --help``.
6
+
7
+ .. automodule:: kubetorch.cli
8
+ :members:
9
+ :show-inheritance:
10
+ :exclude-members: kt_logs, kt_billing, kt_queues, kt_metrics, kt_dashboard, kt_status, kt_docs
@@ -0,0 +1,21 @@
1
+ App
2
+ ===
3
+
4
+ The ``App`` class wraps a Python CLI command. It syncs over the file and any necessary requirements to the specified
5
+ compute, where it runs your file remotely. The file can be any Python file: a basic training script, a script that
6
+ uses kubetorch to deploy further services, or a FastAPI app.
7
+
8
+
9
+ Factory Method
10
+ ~~~~~~~~~~~~~~
11
+
12
+ .. autofunction:: kubetorch.app
13
+
14
+ App Class
15
+ ~~~~~~~~~
16
+
17
+ .. autoclass:: kubetorch.App
18
+ :members:
19
+ :exclude-members: from_name
20
+
21
+ .. automethod:: __init__
@@ -0,0 +1,19 @@
1
+ Cls
2
+ ===
3
+
4
+ The ``Cls`` class is a wrapper around your local Python classes. It can be sent to and live remotely on your compute,
5
+ then be called natively in Python from your local environment, while being run on remote compute.
6
+
7
+ Factory Method
8
+ ~~~~~~~~~~~~~~
9
+
10
+ .. autofunction:: kubetorch.cls
11
+
12
+ Class
13
+ ~~~~~
14
+
15
+ .. autoclass:: kubetorch.Cls
16
+ :members:
17
+ :inherited-members:
18
+
19
+ .. automethod:: __init__
@@ -0,0 +1,25 @@
1
+ Compute
2
+ =======
3
+
4
+ The ``Compute`` class lets you specify the right resources to request for your workloads, and control how that compute
5
+ behaves.
6
+
7
+ Compute Class
8
+ ~~~~~~~~~~~~~~
9
+
10
+ .. autoclass:: kubetorch.Compute
11
+ :members:
12
+ :exclude-members: autoscale, distribute
13
+
14
+ .. automethod:: __init__
15
+
16
+
17
+ Autoscaling
18
+ ~~~~~~~~~~~
19
+
20
+ .. automethod:: kubetorch.Compute.autoscale
21
+
22
+ Distributed
23
+ ~~~~~~~~~~~
24
+
25
+ .. automethod:: kubetorch.Compute.distribute
@@ -0,0 +1,11 @@
1
+ Config
2
+ =======
3
+
4
+ Certain configuration settings can be set globally for Kubetorch, such as a unique username, default namespace, or
5
+ installation url to use. More options to be added soon.
6
+
7
+ Config Class
8
+ ~~~~~~~~~~~~~~
9
+
10
+ .. autoclass:: kubetorch.config.KubetorchConfig
11
+ :members:
@@ -0,0 +1,19 @@
1
+ Fn
2
+ ===
3
+
4
+ The ``Fn`` class is a wrapper around your local Python functions. It can be sent to and live remotely on your compute,
5
+ then be called natively in Python from your local environment, while being run on remote compute.
6
+
7
+ Factory Method
8
+ ~~~~~~~~~~~~~~
9
+
10
+ .. autofunction:: kubetorch.fn
11
+
12
+ Class
13
+ ~~~~~
14
+
15
+ .. autoclass:: kubetorch.Fn
16
+ :members:
17
+ :inherited-members:
18
+
19
+ .. automethod:: __init__
@@ -0,0 +1,14 @@
1
+ Image
2
+ =====
3
+
4
+ The ``Image`` class, which lets you specify a pre-built base Image to use
5
+ at launch time, as well as additional setup steps required for your program, such as installs and env vars.
6
+
7
+ Image Class
8
+ ~~~~~~~~~~~
9
+
10
+ .. autoclass:: kubetorch.Image
11
+ :members:
12
+ :undoc-members:
13
+
14
+ .. automethod:: __init__
@@ -0,0 +1,18 @@
1
+ Secret
2
+ ======
3
+
4
+ Secrets such as provider keys and environment variables can be set when defining compute. These are set at launch time
5
+ and accessible during the scope of your program.
6
+
7
+ Factory Method
8
+ ~~~~~~~~~~~~~~
9
+
10
+ .. autofunction:: kubetorch.secret
11
+
12
+ Class
13
+ ~~~~~
14
+
15
+ .. autoclass:: kubetorch.Secret
16
+ :members:
17
+
18
+ .. automethod:: __init__