Skip to content

Commit 4542dd4

Browse files
committed
feat: add ui cluster creation and deletion buttons
Signed-off-by: Bobbins228 <mcampbel@redhat.com>
1 parent fb59ba6 commit 4542dd4

File tree

2 files changed

+89
-0
lines changed

2 files changed

+89
-0
lines changed

src/codeflare_sdk/cluster/cluster.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
RayCluster,
4343
RayClusterStatus,
4444
)
45+
from .widgets import cluster_up_down_buttons, is_notebook
4546
from kubernetes import client, config
4647
from kubernetes.utils import parse_quantity
4748
import yaml
@@ -51,6 +52,9 @@
5152
from kubernetes import config
5253
from kubernetes.client.rest import ApiException
5354

55+
import ipywidgets as widgets
56+
from IPython.display import display
57+
5458

5559
class Cluster:
5660
"""
@@ -71,6 +75,8 @@ def __init__(self, config: ClusterConfiguration):
7175
self.app_wrapper_yaml = self.create_app_wrapper()
7276
self._job_submission_client = None
7377
self.app_wrapper_name = self.config.name
78+
if is_notebook():
79+
self._cluster_up_down_buttons()
7480

7581
@property
7682
def _client_headers(self):
@@ -156,11 +162,34 @@ def up(self):
156162
plural="appwrappers",
157163
body=aw,
158164
)
165+
print(f"AppWrapper: '{self.config.name}' has successfully been created")
159166
else:
160167
self._component_resources_up(namespace, api_instance)
168+
print(
169+
f"Ray Cluster: '{self.config.name}' has successfully been created"
170+
)
161171
except Exception as e: # pragma: no cover
162172
return _kube_api_error_handling(e)
163173

174+
def _cluster_up_down_buttons(self):
175+
up_button, delete_button = cluster_up_down_buttons(self.config.appwrapper)
176+
output = widgets.Output()
177+
# Display the buttons in an HBox
178+
display(widgets.HBox([up_button, delete_button]), output)
179+
180+
def on_up_button_clicked(b):
181+
with output:
182+
output.clear_output()
183+
self.up()
184+
185+
def on_down_button_clicked(b):
186+
with output:
187+
output.clear_output()
188+
self.down()
189+
190+
up_button.on_click(on_up_button_clicked)
191+
delete_button.on_click(on_down_button_clicked)
192+
164193
def _throw_for_no_raycluster(self):
165194
api_instance = client.CustomObjectsApi(api_config_handler())
166195
try:
@@ -198,8 +227,12 @@ def down(self):
198227
plural="appwrappers",
199228
name=self.app_wrapper_name,
200229
)
230+
print(f"AppWrapper: '{self.config.name}' has successfully been deleted")
201231
else:
202232
self._component_resources_down(namespace, api_instance)
233+
print(
234+
f"Ray Cluster: '{self.config.name}' has successfully been deleted"
235+
)
203236
except Exception as e: # pragma: no cover
204237
return _kube_api_error_handling(e)
205238

src/codeflare_sdk/cluster/widgets.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# Copyright 2022 IBM, Red Hat
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
"""
16+
The widgets sub-module contains the ui widgets created using the ipywidgets package.
17+
"""
18+
import ipywidgets as widgets
19+
import os
20+
21+
22+
def cluster_up_down_buttons(appwrapper: bool) -> widgets.Button:
23+
"""
24+
The cluster_up_down_buttons function returns two button widgets for a create and delete button.
25+
The function accepts a bool(appwrapper) for distinguishing between resource type for the tool tip.
26+
"""
27+
resource = "Ray Cluster"
28+
if appwrapper:
29+
resource = "AppWrapper"
30+
31+
up_button = widgets.Button(
32+
description="Cluster Up",
33+
tooltip=f"Create the {resource}",
34+
icon="play",
35+
)
36+
37+
delete_button = widgets.Button(
38+
description="Cluster Down",
39+
tooltip=f"Delete the {resource}",
40+
icon="trash",
41+
)
42+
43+
return up_button, delete_button
44+
45+
46+
def is_notebook() -> bool:
47+
"""
48+
The is_notebook function checks if Jupyter Notebook environment variables exist in the given environment and return True/False based on that.
49+
"""
50+
if (
51+
"PYDEVD_IPYTHON_COMPATIBLE_DEBUGGING" in os.environ
52+
or "JPY_SESSION_NAME" in os.environ
53+
): # If running Jupyter NBs in VsCode or RHOAI/ODH display UI buttons
54+
return True
55+
else:
56+
return False

0 commit comments

Comments
 (0)