51
51
from kubernetes import config
52
52
from kubernetes .client .rest import ApiException
53
53
54
+ import ipywidgets as widgets
55
+ from IPython .display import display
56
+
54
57
55
58
class Cluster :
56
59
"""
@@ -71,6 +74,8 @@ def __init__(self, config: ClusterConfiguration):
71
74
self .app_wrapper_yaml = self .create_app_wrapper ()
72
75
self ._job_submission_client = None
73
76
self .app_wrapper_name = self .config .name
77
+ if _is_notebook ():
78
+ self ._cluster_up_down_buttons ()
74
79
75
80
@property
76
81
def _client_headers (self ):
@@ -156,11 +161,42 @@ def up(self):
156
161
plural = "appwrappers" ,
157
162
body = aw ,
158
163
)
164
+ print (f"AppWrapper: '{ self .config .name } ' has successfully been created" )
159
165
else :
160
166
self ._component_resources_up (namespace , api_instance )
167
+ print (
168
+ f"Ray Cluster: '{ self .config .name } ' has successfully been created"
169
+ )
161
170
except Exception as e : # pragma: no cover
162
171
return _kube_api_error_handling (e )
163
172
173
+ def _cluster_up_down_buttons (self ):
174
+ delete_button = widgets .Button (
175
+ description = "Cluster Down" ,
176
+ icon = "trash" ,
177
+ )
178
+ up_button = widgets .Button (
179
+ description = "Cluster Up" ,
180
+ icon = "play" ,
181
+ )
182
+
183
+ output = widgets .Output ()
184
+ # Display the buttons in an HBox
185
+ display (widgets .HBox ([delete_button , up_button ]), output )
186
+
187
+ def on_up_button_clicked (b ):
188
+ with output :
189
+ output .clear_output ()
190
+ self .up ()
191
+
192
+ def on_down_button_clicked (b ):
193
+ with output :
194
+ output .clear_output ()
195
+ self .down ()
196
+
197
+ up_button .on_click (on_up_button_clicked )
198
+ delete_button .on_click (on_down_button_clicked )
199
+
164
200
def _throw_for_no_raycluster (self ):
165
201
api_instance = client .CustomObjectsApi (api_config_handler ())
166
202
try :
@@ -198,8 +234,12 @@ def down(self):
198
234
plural = "appwrappers" ,
199
235
name = self .app_wrapper_name ,
200
236
)
237
+ print (f"AppWrapper: '{ self .config .name } ' has successfully been deleted" )
201
238
else :
202
239
self ._component_resources_down (namespace , api_instance )
240
+ print (
241
+ f"Ray Cluster: '{ self .config .name } ' has successfully been deleted"
242
+ )
203
243
except Exception as e : # pragma: no cover
204
244
return _kube_api_error_handling (e )
205
245
@@ -905,3 +945,13 @@ def _copy_to_ray(cluster: Cluster) -> RayCluster:
905
945
if ray .status == CodeFlareClusterStatus .READY :
906
946
ray .status = RayClusterStatus .READY
907
947
return ray
948
+
949
+
950
+ def _is_notebook () -> bool :
951
+ if (
952
+ "PYDEVD_IPYTHON_COMPATIBLE_DEBUGGING" in os .environ
953
+ or "JPY_SESSION_NAME" in os .environ
954
+ ): # If running Jupyter NBs in VsCode or RHOAI/ODH display UI buttons
955
+ return True
956
+ else :
957
+ return False
0 commit comments