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.
Files changed (92) hide show
  1. kubetorch/__init__.py +59 -0
  2. kubetorch/cli.py +1939 -0
  3. kubetorch/cli_utils.py +967 -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 +269 -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 +159 -0
  28. kubetorch/resources/callables/fn/__init__.py +0 -0
  29. kubetorch/resources/callables/fn/fn.py +140 -0
  30. kubetorch/resources/callables/module.py +1315 -0
  31. kubetorch/resources/callables/utils.py +203 -0
  32. kubetorch/resources/compute/__init__.py +0 -0
  33. kubetorch/resources/compute/app.py +253 -0
  34. kubetorch/resources/compute/compute.py +2414 -0
  35. kubetorch/resources/compute/decorators.py +137 -0
  36. kubetorch/resources/compute/utils.py +1026 -0
  37. kubetorch/resources/compute/websocket.py +135 -0
  38. kubetorch/resources/images/__init__.py +1 -0
  39. kubetorch/resources/images/image.py +412 -0
  40. kubetorch/resources/images/images.py +64 -0
  41. kubetorch/resources/secrets/__init__.py +2 -0
  42. kubetorch/resources/secrets/kubernetes_secrets_client.py +377 -0
  43. kubetorch/resources/secrets/provider_secrets/__init__.py +0 -0
  44. kubetorch/resources/secrets/provider_secrets/anthropic_secret.py +12 -0
  45. kubetorch/resources/secrets/provider_secrets/aws_secret.py +16 -0
  46. kubetorch/resources/secrets/provider_secrets/azure_secret.py +14 -0
  47. kubetorch/resources/secrets/provider_secrets/cohere_secret.py +12 -0
  48. kubetorch/resources/secrets/provider_secrets/gcp_secret.py +16 -0
  49. kubetorch/resources/secrets/provider_secrets/github_secret.py +13 -0
  50. kubetorch/resources/secrets/provider_secrets/huggingface_secret.py +20 -0
  51. kubetorch/resources/secrets/provider_secrets/kubeconfig_secret.py +12 -0
  52. kubetorch/resources/secrets/provider_secrets/lambda_secret.py +13 -0
  53. kubetorch/resources/secrets/provider_secrets/langchain_secret.py +12 -0
  54. kubetorch/resources/secrets/provider_secrets/openai_secret.py +11 -0
  55. kubetorch/resources/secrets/provider_secrets/pinecone_secret.py +12 -0
  56. kubetorch/resources/secrets/provider_secrets/providers.py +92 -0
  57. kubetorch/resources/secrets/provider_secrets/ssh_secret.py +12 -0
  58. kubetorch/resources/secrets/provider_secrets/wandb_secret.py +11 -0
  59. kubetorch/resources/secrets/secret.py +224 -0
  60. kubetorch/resources/secrets/secret_factory.py +64 -0
  61. kubetorch/resources/secrets/utils.py +222 -0
  62. kubetorch/resources/volumes/__init__.py +0 -0
  63. kubetorch/resources/volumes/volume.py +340 -0
  64. kubetorch/servers/__init__.py +0 -0
  65. kubetorch/servers/http/__init__.py +0 -0
  66. kubetorch/servers/http/distributed_utils.py +2968 -0
  67. kubetorch/servers/http/http_client.py +802 -0
  68. kubetorch/servers/http/http_server.py +1622 -0
  69. kubetorch/servers/http/server_metrics.py +255 -0
  70. kubetorch/servers/http/utils.py +722 -0
  71. kubetorch/serving/__init__.py +0 -0
  72. kubetorch/serving/autoscaling.py +153 -0
  73. kubetorch/serving/base_service_manager.py +344 -0
  74. kubetorch/serving/constants.py +77 -0
  75. kubetorch/serving/deployment_service_manager.py +431 -0
  76. kubetorch/serving/knative_service_manager.py +487 -0
  77. kubetorch/serving/raycluster_service_manager.py +526 -0
  78. kubetorch/serving/service_manager.py +18 -0
  79. kubetorch/serving/templates/deployment_template.yaml +17 -0
  80. kubetorch/serving/templates/knative_service_template.yaml +19 -0
  81. kubetorch/serving/templates/kt_setup_template.sh.j2 +91 -0
  82. kubetorch/serving/templates/pod_template.yaml +198 -0
  83. kubetorch/serving/templates/raycluster_service_template.yaml +42 -0
  84. kubetorch/serving/templates/raycluster_template.yaml +35 -0
  85. kubetorch/serving/templates/service_template.yaml +21 -0
  86. kubetorch/serving/templates/workerset_template.yaml +36 -0
  87. kubetorch/serving/utils.py +344 -0
  88. kubetorch/utils.py +263 -0
  89. kubetorch-0.2.5.dist-info/METADATA +75 -0
  90. kubetorch-0.2.5.dist-info/RECORD +92 -0
  91. kubetorch-0.2.5.dist-info/WHEEL +4 -0
  92. kubetorch-0.2.5.dist-info/entry_points.txt +5 -0
@@ -0,0 +1,159 @@
1
+ from kubetorch.logger import get_logger
2
+ from kubetorch.resources.callables.module import Module
3
+ from kubetorch.resources.callables.utils import extract_pointers, SHELL_COMMANDS
4
+
5
+ logger = get_logger(__name__)
6
+
7
+
8
+ class Cls(Module):
9
+ MODULE_TYPE = "cls"
10
+
11
+ def __init__(
12
+ self,
13
+ name: str,
14
+ pointers: tuple = None,
15
+ init_args: dict = None,
16
+ ):
17
+ """
18
+ Initialize a Cls object for remote class execution.
19
+
20
+ .. note::
21
+
22
+ To create a Cls, please use the factory method :func:`cls`.
23
+
24
+ Args:
25
+ name (str): The name of the class to be executed remotely.
26
+ pointers (tuple, optional): A tuple containing pointers/references needed to locate and execute
27
+ the class, typically including module path and class name.
28
+ init_args (dict, optional): Dictionary of arguments to pass to the class constructor.
29
+ Defaults to None.
30
+ """
31
+ self._init_args = init_args
32
+ if not pointers:
33
+ # local to the class definition
34
+ pointers = extract_pointers(self.__class__)
35
+
36
+ super().__init__(name=name, pointers=pointers)
37
+
38
+ def __getattr__(self, attr_name):
39
+ if attr_name in SHELL_COMMANDS:
40
+ return getattr(self.compute, attr_name)
41
+
42
+ if not attr_name.startswith("_") and attr_name not in CLASS_METHODS:
43
+
44
+ def remote_method_wrapper(*args, **kwargs):
45
+ async_ = kwargs.pop("async_", self.async_)
46
+
47
+ if async_:
48
+ return self._call_async(attr_name, *args, **kwargs)
49
+ else:
50
+ return self._call_sync(attr_name, *args, **kwargs)
51
+
52
+ return remote_method_wrapper
53
+
54
+ @property
55
+ def init_args(self):
56
+ return self._init_args
57
+
58
+ @init_args.setter
59
+ def init_args(self, value):
60
+ self._init_args = value
61
+
62
+ def _call_sync(self, method_name, *args, **kwargs):
63
+ """Synchronous call implementation."""
64
+ client = self._client(method_name=method_name)
65
+ stream_logs = kwargs.pop("stream_logs", None)
66
+ stream_metrics = kwargs.pop("stream_metrics", None)
67
+ pdb = kwargs.pop("pdb", None)
68
+ if pdb:
69
+ logger.info(f"Debugging remote cls {self.name}.{method_name}")
70
+ elif stream_logs:
71
+ logger.info(f"Calling remote cls {self.name}.{method_name}")
72
+
73
+ response = client.call_method(
74
+ self.endpoint(method_name),
75
+ stream_logs=stream_logs,
76
+ stream_metrics=stream_metrics,
77
+ headers=self.request_headers,
78
+ body={"args": list(args), "kwargs": kwargs},
79
+ pdb=pdb,
80
+ serialization=kwargs.pop("serialization", self.serialization),
81
+ )
82
+ return response
83
+
84
+ async def _call_async(self, method_name, *args, **kwargs):
85
+ """Asynchronous call implementation."""
86
+ client = self._client(method_name=method_name)
87
+ stream_logs = kwargs.pop("stream_logs", None)
88
+ stream_metrics = kwargs.pop("stream_metrics", None)
89
+ pdb = kwargs.pop("pdb", None)
90
+ if pdb:
91
+ logger.info(f"Debugging remote cls {self.name}.{method_name} (async)")
92
+ elif stream_logs:
93
+ logger.info(f"Calling remote cls {self.name}.{method_name} (async)")
94
+
95
+ response = await client.call_method_async(
96
+ self.endpoint(method_name),
97
+ stream_logs=stream_logs,
98
+ stream_metrics=stream_metrics,
99
+ headers=self.request_headers,
100
+ body={"args": list(args), "kwargs": kwargs},
101
+ pdb=pdb,
102
+ serialization=kwargs.pop("serialization", self.serialization),
103
+ )
104
+ return response
105
+
106
+
107
+ def cls(class_obj=None, name: str = None, get_if_exists=True, reload_prefixes=None):
108
+ """
109
+ Builds an instance of :class:`Cls`.
110
+
111
+ Args:
112
+ class_obj (Cls, optional): The class to be executed remotely. If not provided and name is
113
+ specified, will reload an existing cls object.
114
+ name (str, optional): The name to give the remote class. If not provided,
115
+ will use the class's name.
116
+ get_if_exists (bool, optional):
117
+ Controls how service lookup is performed when loading by name.
118
+
119
+ - If True (default): Attempt to find an existing service using a standard fallback order
120
+ (e.g., username, git branch, then prod).
121
+ - If False: Only look for an exact name match; do not attempt any fallback.
122
+
123
+ This allows you to control whether and how the loader should fall back to alternate
124
+ versions of a service (such as QA, prod, or CI versions) if the exact name is not found.
125
+ reload_prefixes (Union[str, List[str]], optional):
126
+ A list of prefixes to use when reloading the class (e.g., ["qa", "prod", "git-branch-name"]).
127
+ If not provided, will use the current username, git branch, and prod.
128
+
129
+ Example:
130
+
131
+ .. code-block:: python
132
+
133
+ import kubetorch as kt
134
+
135
+ remote_cls = kt.cls(MyClass, name="my-class").to(kt.Compute(cpus=".1"))
136
+ result = remote_cls.my_method(1, 2)
137
+ """
138
+ if class_obj:
139
+ cls_pointers = extract_pointers(class_obj)
140
+ name = name or (cls_pointers[2] if cls_pointers else cls.__name__)
141
+ new_cls = Cls(
142
+ name=name,
143
+ pointers=cls_pointers,
144
+ )
145
+ new_cls.get_if_exists = get_if_exists
146
+ new_cls.reload_prefixes = reload_prefixes or []
147
+ return new_cls
148
+
149
+ if name is None:
150
+ raise ValueError("Name must be provided to reload an existing class")
151
+
152
+ if get_if_exists is False:
153
+ raise ValueError("Either provide a class object or a name with get_if_exists=True to reload an existing class")
154
+
155
+ reloaded_cls = Cls.from_name(name, reload_prefixes=reload_prefixes)
156
+ return reloaded_cls
157
+
158
+
159
+ CLASS_METHODS = dir(Cls)
File without changes
@@ -0,0 +1,140 @@
1
+ from kubetorch.logger import get_logger
2
+ from kubetorch.resources.callables.module import Module
3
+ from kubetorch.resources.callables.utils import extract_pointers, prepare_notebook_fn
4
+
5
+ logger = get_logger(__name__)
6
+
7
+
8
+ class Fn(Module):
9
+ MODULE_TYPE = "fn"
10
+
11
+ def __init__(
12
+ self,
13
+ name: str,
14
+ pointers: tuple = None,
15
+ ):
16
+ """
17
+ Initialize a Fn object for remote function execution.
18
+
19
+ .. note::
20
+
21
+ To create a Function, please use the factory method :func:`fn`.
22
+
23
+ Args:
24
+ name (str): The name of the function to be executed remotely.
25
+ pointers (tuple, optional): A tuple containing pointers/references needed to locate and execute
26
+ the function, typically including module path, class name (if applicable), and
27
+ function name.
28
+ """
29
+ super().__init__(name=name, pointers=pointers)
30
+
31
+ def __call__(self, *args, **kwargs):
32
+ async_ = kwargs.pop("async_", self.async_)
33
+
34
+ if async_:
35
+ return self._call_async(*args, **kwargs)
36
+ else:
37
+ return self._call_sync(*args, **kwargs)
38
+
39
+ def _call_sync(self, *args, **kwargs):
40
+ client = self._client()
41
+ stream_logs = kwargs.pop("stream_logs", None)
42
+ stream_metrics = kwargs.pop("stream_metrics", None)
43
+ pdb = kwargs.pop("pdb", None)
44
+ if pdb:
45
+ logger.info(f"Debugging remote function {self.name}")
46
+ elif stream_logs:
47
+ logger.info(f"Calling remote function {self.name}")
48
+
49
+ response = client.call_method(
50
+ self.endpoint(),
51
+ stream_logs=stream_logs,
52
+ stream_metrics=stream_metrics,
53
+ headers=self.request_headers,
54
+ body={"args": list(args), "kwargs": kwargs},
55
+ pdb=pdb,
56
+ serialization=kwargs.pop("serialization", self.serialization),
57
+ )
58
+ return response
59
+
60
+ async def _call_async(self, *args, **kwargs):
61
+ """Asynchronous call implementation."""
62
+ client = self._client()
63
+ stream_logs = kwargs.pop("stream_logs", None)
64
+ stream_metrics = kwargs.pop("stream_metrics", None)
65
+ pdb = kwargs.pop("pdb", None)
66
+ if pdb:
67
+ logger.info(f"Debugging remote function {self.name}")
68
+ elif stream_logs:
69
+ logger.info(f"Calling remote function {self.name}")
70
+
71
+ response = await client.call_method_async(
72
+ self.endpoint(),
73
+ stream_logs=stream_logs,
74
+ stream_metrics=stream_metrics,
75
+ headers=self.request_headers,
76
+ body={"args": list(args), "kwargs": kwargs},
77
+ pdb=pdb,
78
+ serialization=kwargs.pop("serialization", self.serialization),
79
+ )
80
+ return response
81
+
82
+
83
+ def fn(function_obj=None, name: str = None, get_if_exists=True, reload_prefixes=None):
84
+ """
85
+ Builds an instance of :class:`Fn`.
86
+
87
+ Args:
88
+ function_obj (Fn, optional): The function to be executed remotely. If not provided and name is
89
+ specified, will reload an existing fn object.
90
+ name (str, optional): The name to give the remote function. If not provided,
91
+ will use the function's name.
92
+ get_if_exists (bool, optional):
93
+ Controls how service lookup is performed when loading by name.
94
+
95
+ - If True (default): Attempt to find an existing service using a standard fallback order
96
+ (e.g., username, git branch, then prod).
97
+ - If False: Only look for an exact name match; do not attempt any fallback.
98
+
99
+ This allows you to control whether and how the loader should fall back to alternate
100
+ versions of a service (such as QA, prod, or CI versions) if the exact name is not found.
101
+ reload_prefixes (Union[str, List[str]], optional):
102
+ A list of prefixes to use when reloading the function (e.g., ["qa", "prod", "git-branch-name"]).
103
+ If not provided, will use the current username, git branch, and prod.
104
+
105
+ Example:
106
+
107
+ .. code-block:: python
108
+
109
+ import kubetorch as kt
110
+
111
+ remote_fn = kt.fn(my_func, name="some-func").to(kt.Compute(cpus=".1"))
112
+ result = remote_fn(1, 2)
113
+ """
114
+ if function_obj:
115
+ fn_pointers = extract_pointers(function_obj)
116
+ if fn_pointers[1] == "notebook":
117
+ fn_pointers = prepare_notebook_fn(fn_pointers, name=fn_pointers[2] or name)
118
+
119
+ name = name or (fn_pointers[2] if fn_pointers else function_obj.__name__)
120
+ new_fn = Fn(
121
+ name=name,
122
+ pointers=fn_pointers,
123
+ )
124
+ new_fn.get_if_exists = get_if_exists
125
+ new_fn.reload_prefixes = reload_prefixes or []
126
+ return new_fn
127
+
128
+ if name is None:
129
+ raise ValueError("Name must be provided to reload an existing function")
130
+
131
+ if get_if_exists is False:
132
+ raise ValueError(
133
+ "Either provide a function object or a name with get_if_exists=True to reload an existing function"
134
+ )
135
+
136
+ reloaded_fn = Fn.from_name(name, reload_prefixes=reload_prefixes)
137
+ return reloaded_fn
138
+
139
+
140
+ FN_METHODS = dir(Fn)