Skip to content

Commit e95e6d5

Browse files
Add refresh button to widgets UI
1 parent 13658b8 commit e95e6d5

File tree

2 files changed

+54
-26
lines changed

2 files changed

+54
-26
lines changed

src/codeflare_sdk/common/widgets/test_widgets.py

+10
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,9 @@ def test_ray_cluster_manager_widgets_init(mocker, capsys):
296296
assert (
297297
ray_cluster_manager_instance.ray_dashboard_button == mock_button.return_value
298298
), "ray_dashboard_button is not set correctly"
299+
assert (
300+
ray_cluster_manager_instance.refresh_data_button == mock_button.return_value
301+
), "refresh_data_button is not set correctly"
299302
assert (
300303
ray_cluster_manager_instance.raycluster_data_output == mock_output.return_value
301304
), "raycluster_data_output is not set correctly"
@@ -310,6 +313,7 @@ def test_ray_cluster_manager_widgets_init(mocker, capsys):
310313
mock_delete_button = MagicMock()
311314
mock_list_jobs_button = MagicMock()
312315
mock_ray_dashboard_button = MagicMock()
316+
mock_refresh_dataframe_button = MagicMock()
313317

314318
mock_javascript = mocker.patch("codeflare_sdk.common.widgets.widgets.Javascript")
315319
ray_cluster_manager_instance.url_output = MagicMock()
@@ -332,6 +336,12 @@ def test_ray_cluster_manager_widgets_init(mocker, capsys):
332336
f'window.open("{mock_dashboard_uri.return_value}/#/jobs", "_blank");'
333337
)
334338

339+
# Simulate clicking the refresh data button
340+
ray_cluster_manager_instance._on_refresh_data_button_click(
341+
mock_refresh_dataframe_button
342+
)
343+
mock_fetch_cluster_data.assert_called_with(namespace)
344+
335345
# Simulate clicking the Ray dashboard button
336346
ray_cluster_manager_instance.classification_widget.value = "test-cluster-1"
337347
ray_cluster_manager_instance._on_ray_dashboard_button_click(

src/codeflare_sdk/common/widgets/widgets.py

+44-26
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,12 @@ def __init__(self, ray_clusters_df: pd.DataFrame, namespace: str = None):
7474
tooltip="Open the Ray Dashboard in a new tab",
7575
layout=widgets.Layout(width="auto"),
7676
)
77+
self.refresh_data_button = widgets.Button(
78+
description="Refresh Data",
79+
icon="refresh",
80+
tooltip="Refresh the list of Ray Clusters",
81+
layout=widgets.Layout(width="auto", left="1em"),
82+
)
7783

7884
# Set up interactions
7985
self._initialize_callbacks()
@@ -95,6 +101,7 @@ def _initialize_callbacks(self):
95101
self.ray_dashboard_button.on_click(
96102
lambda b: self._on_ray_dashboard_button_click(b)
97103
)
104+
self.refresh_data_button.on_click(lambda b: self._on_refresh_button_click(b))
98105

99106
def _trigger_initial_display(self):
100107
"""
@@ -138,31 +145,17 @@ def _on_delete_button_click(self, b):
138145
_on_delete_button_click handles the event when the Delete Button is clicked, deleting the selected cluster.
139146
"""
140147
cluster_name = self.classification_widget.value
141-
namespace = self.ray_clusters_df[
142-
self.ray_clusters_df["Name"] == self.classification_widget.value
143-
]["Namespace"].values[0]
144148

145-
_delete_cluster(cluster_name, namespace)
149+
_delete_cluster(cluster_name, self.namespace)
146150

147151
with self.user_output:
148152
self.user_output.clear_output()
149153
print(
150-
f"Cluster {cluster_name} in the {namespace} namespace was deleted successfully."
154+
f"Cluster {cluster_name} in the {self.namespace} namespace was deleted successfully."
151155
)
152156

153157
# Refresh the dataframe
154-
new_df = _fetch_cluster_data(namespace)
155-
self.ray_clusters_df = new_df
156-
if new_df.empty:
157-
self.classification_widget.close()
158-
self.delete_button.close()
159-
self.list_jobs_button.close()
160-
self.ray_dashboard_button.close()
161-
with self.raycluster_data_output:
162-
self.raycluster_data_output.clear_output()
163-
print(f"No clusters found in the {namespace} namespace.")
164-
else:
165-
self.classification_widget.options = new_df["Name"].tolist()
158+
self._refresh_dataframe()
166159

167160
def _on_list_jobs_button_click(self, b):
168161
"""
@@ -171,15 +164,12 @@ def _on_list_jobs_button_click(self, b):
171164
from codeflare_sdk import Cluster
172165

173166
cluster_name = self.classification_widget.value
174-
namespace = self.ray_clusters_df[
175-
self.ray_clusters_df["Name"] == self.classification_widget.value
176-
]["Namespace"].values[0]
177167

178168
# Suppress from Cluster Object initialisation widgets and outputs
179169
with widgets.Output(), contextlib.redirect_stdout(
180170
io.StringIO()
181171
), contextlib.redirect_stderr(io.StringIO()):
182-
cluster = Cluster(ClusterConfiguration(cluster_name, namespace))
172+
cluster = Cluster(ClusterConfiguration(cluster_name, self.namespace))
183173
dashboard_url = cluster.cluster_dashboard_uri()
184174

185175
with self.user_output:
@@ -197,15 +187,12 @@ def _on_ray_dashboard_button_click(self, b):
197187
from codeflare_sdk import Cluster
198188

199189
cluster_name = self.classification_widget.value
200-
namespace = self.ray_clusters_df[
201-
self.ray_clusters_df["Name"] == self.classification_widget.value
202-
]["Namespace"].values[0]
203190

204191
# Suppress from Cluster Object initialisation widgets and outputs
205192
with widgets.Output(), contextlib.redirect_stdout(
206193
io.StringIO()
207194
), contextlib.redirect_stderr(io.StringIO()):
208-
cluster = Cluster(ClusterConfiguration(cluster_name, namespace))
195+
cluster = Cluster(ClusterConfiguration(cluster_name, self.namespace))
209196
dashboard_url = cluster.cluster_dashboard_uri()
210197

211198
with self.user_output:
@@ -214,11 +201,42 @@ def _on_ray_dashboard_button_click(self, b):
214201
with self.url_output:
215202
display(Javascript(f'window.open("{dashboard_url}", "_blank");'))
216203

204+
def _on_refresh_data_button_click(self, b):
205+
"""
206+
_on_refresh_button_click handles the event when the Refresh Data button is clicked, refreshing the list of Ray Clusters.
207+
"""
208+
self.refresh_data_button.disabled = True
209+
self._refresh_dataframe()
210+
self.refresh_data_button.disabled = False
211+
212+
def _refresh_dataframe(self):
213+
"""
214+
_refresh_data function refreshes the list of Ray Clusters.
215+
"""
216+
new_df = _fetch_cluster_data(self.namespace)
217+
self.ray_clusters_df = new_df
218+
if new_df.empty:
219+
self.classification_widget.close()
220+
self.delete_button.close()
221+
self.list_jobs_button.close()
222+
self.ray_dashboard_button.close()
223+
self.refresh_data_button.close()
224+
with self.raycluster_data_output:
225+
self.raycluster_data_output.clear_output()
226+
print(f"No clusters found in the {self.namespace} namespace.")
227+
else:
228+
self.classification_widget.options = new_df["Name"].tolist()
229+
217230
def display_widgets(self):
218231
display(widgets.VBox([self.classification_widget, self.raycluster_data_output]))
219232
display(
220233
widgets.HBox(
221-
[self.delete_button, self.list_jobs_button, self.ray_dashboard_button]
234+
[
235+
self.delete_button,
236+
self.list_jobs_button,
237+
self.ray_dashboard_button,
238+
self.refresh_data_button,
239+
]
222240
),
223241
self.url_output,
224242
self.user_output,

0 commit comments

Comments
 (0)