18
18
import contextlib
19
19
import io
20
20
import os
21
- from time import sleep
21
+ import warnings
22
22
import time
23
23
import codeflare_sdk
24
24
from kubernetes import client
@@ -103,7 +103,13 @@ def is_notebook() -> bool:
103
103
104
104
105
105
def view_clusters (namespace : str = None ):
106
- """view_clusters function will display existing clusters with their specs, and handle user interactions."""
106
+ """
107
+ view_clusters function will display existing clusters with their specs, and handle user interactions.
108
+ """
109
+ if not is_notebook ():
110
+ warnings .warn ("view_clusters can only be used in a Jupyter Notebook environment." )
111
+ return # Exit function if not in Jupyter Notebook
112
+
107
113
from .cluster import get_current_namespace
108
114
if not namespace :
109
115
namespace = get_current_namespace ()
@@ -112,13 +118,13 @@ def view_clusters(namespace: str = None):
112
118
raycluster_data_output = widgets .Output ()
113
119
url_output = widgets .Output ()
114
120
115
- df = _fetch_cluster_data (namespace )
116
- if df .empty :
121
+ ray_clusters_df = _fetch_cluster_data (namespace )
122
+ if ray_clusters_df .empty :
117
123
print (f"No clusters found in the { namespace } namespace." )
118
124
return
119
125
120
126
classification_widget = widgets .ToggleButtons (
121
- options = df ["Name" ].tolist (), value = df ["Name" ].tolist ()[0 ],
127
+ options = ray_clusters_df ["Name" ].tolist (), value = ray_clusters_df ["Name" ].tolist ()[0 ],
122
128
description = 'Select an existing cluster:' ,
123
129
)
124
130
# Setting the initial value to trigger the event handler to display the cluster details.
@@ -132,28 +138,31 @@ def view_clusters(namespace: str = None):
132
138
icon = 'trash' ,
133
139
tooltip = "Delete the selected cluster"
134
140
)
135
- delete_button .on_click (lambda b : _on_delete_button_click (b , classification_widget , df , raycluster_data_output , user_output , delete_button , list_jobs_button , ray_dashboard_button ))
141
+ delete_button .on_click (lambda b : _on_delete_button_click (b , classification_widget , ray_clusters_df , raycluster_data_output , user_output , delete_button , list_jobs_button , ray_dashboard_button ))
136
142
137
143
list_jobs_button = widgets .Button (
138
144
description = 'View Jobs' ,
139
145
icon = 'suitcase' ,
140
146
tooltip = "Open the Ray Job Dashboard"
141
147
)
142
- list_jobs_button .on_click (lambda b : _on_list_jobs_button_click (b , classification_widget , df , user_output , url_output ))
148
+ list_jobs_button .on_click (lambda b : _on_list_jobs_button_click (b , classification_widget , ray_clusters_df , user_output , url_output ))
143
149
144
150
ray_dashboard_button = widgets .Button (
145
151
description = 'Open Ray Dashboard' ,
146
152
icon = 'dashboard' ,
147
153
tooltip = "Open the Ray Dashboard in a new tab" ,
148
154
layout = widgets .Layout (width = 'auto' ),
149
155
)
150
- ray_dashboard_button .on_click (lambda b : _on_ray_dashboard_button_click (b , classification_widget , df , user_output , url_output ))
156
+ ray_dashboard_button .on_click (lambda b : _on_ray_dashboard_button_click (b , classification_widget , ray_clusters_df , user_output , url_output ))
151
157
152
158
display (widgets .VBox ([classification_widget , raycluster_data_output ]))
153
159
display (widgets .HBox ([delete_button , list_jobs_button , ray_dashboard_button ]), url_output , user_output )
154
160
155
- # Handles the event when a cluster is selected from the toggle buttons, updating the output with cluster details.
161
+
156
162
def _on_cluster_click (selection_change , raycluster_data_output : widgets .Output , namespace : str , classification_widget : widgets .ToggleButtons ):
163
+ """
164
+ _on_cluster_click handles the event when a cluster is selected from the toggle buttons, updating the output with cluster details.
165
+ """
157
166
new_value = selection_change ["new" ]
158
167
raycluster_data_output .clear_output ()
159
168
df = _fetch_cluster_data (namespace )
@@ -163,6 +172,9 @@ def _on_cluster_click(selection_change, raycluster_data_output: widgets.Output,
163
172
164
173
165
174
def _on_delete_button_click (b , classification_widget : widgets .ToggleButtons , df : pd .DataFrame , raycluster_data_output : widgets .Output , user_output : widgets .Output , delete_button : widgets .Button , list_jobs_button : widgets .Button , ray_dashboard_button : widgets .Button ):
175
+ """
176
+ _on_delete_button_click handles the event when the Delete Button is clicked, deleting the selected cluster.
177
+ """
166
178
cluster_name = classification_widget .value
167
179
namespace = df [df ["Name" ]== classification_widget .value ]["Namespace" ].values [0 ]
168
180
@@ -186,6 +198,9 @@ def _on_delete_button_click(b, classification_widget: widgets.ToggleButtons, df:
186
198
classification_widget .options = new_df ["Name" ].tolist ()
187
199
188
200
def _on_ray_dashboard_button_click (b , classification_widget : widgets .ToggleButtons , df : pd .DataFrame , user_output : widgets .Output , url_output : widgets .Output ):
201
+ """
202
+ _on_ray_dashboard_button_click handles the event when the Open Ray Dashboard button is clicked, opening the Ray Dashboard in a new tab
203
+ """
189
204
from codeflare_sdk .cluster import Cluster
190
205
cluster_name = classification_widget .value
191
206
namespace = df [df ["Name" ]== classification_widget .value ]["Namespace" ].values [0 ]
@@ -202,6 +217,9 @@ def _on_ray_dashboard_button_click(b, classification_widget: widgets.ToggleButto
202
217
display (Javascript (f'window.open("{ dashboard_url } ", "_blank");' ))
203
218
204
219
def _on_list_jobs_button_click (b , classification_widget : widgets .ToggleButtons , df : pd .DataFrame , user_output : widgets .Output , url_output : widgets .Output ):
220
+ """
221
+ _on_list_jobs_button_click handles the event when the View Jobs button is clicked, opening the Ray Jobs Dashboard in a new tab
222
+ """
205
223
from codeflare_sdk .cluster import Cluster
206
224
cluster_name = classification_widget .value
207
225
namespace = df [df ["Name" ]== classification_widget .value ]["Namespace" ].values [0 ]
@@ -217,12 +235,17 @@ def _on_list_jobs_button_click(b, classification_widget: widgets.ToggleButtons,
217
235
with url_output :
218
236
display (Javascript (f'window.open("{ dashboard_url } /#/jobs", "_blank");' ))
219
237
238
+
220
239
def _delete_cluster (
221
240
cluster_name : str ,
222
241
namespace : str ,
223
242
timeout : int = 5 ,
224
243
interval : int = 1 ,
225
244
):
245
+ """
246
+ _delete_cluster function deletes the cluster with the given name and namespace.
247
+ It optionally waits for the cluster to be deleted.
248
+ """
226
249
from .cluster import _check_aw_exists
227
250
228
251
try :
@@ -276,6 +299,9 @@ def _delete_cluster(
276
299
277
300
278
301
def _fetch_cluster_data (namespace ):
302
+ """
303
+ _fetch_cluster_data function fetches all clusters and their spec in a given namespace and returns a DataFrame.
304
+ """
279
305
from .cluster import list_all_clusters
280
306
rayclusters = list_all_clusters (namespace , False )
281
307
if not rayclusters :
@@ -323,6 +349,9 @@ def _fetch_cluster_data(namespace):
323
349
324
350
325
351
def _format_status (status ):
352
+ """
353
+ _format_status function formats the status enum.
354
+ """
326
355
status_map = {
327
356
RayClusterStatus .READY : '<span style="color: green;">Ready ✓</span>' ,
328
357
RayClusterStatus .SUSPENDED : '<span style="color: #007BFF;">Suspended ❄️</span>' ,
0 commit comments