Spaces:
Running
Running
File size: 8,439 Bytes
4cf9e66 eeffeaa 4cf9e66 eeffeaa 4cf9e66 9648b26 4cf9e66 9648b26 4cf9e66 9648b26 4cf9e66 9648b26 4cf9e66 9648b26 4cf9e66 8593789 4206178 8199533 4206178 8593789 4206178 4cf9e66 eeffeaa 4cf9e66 eeffeaa 4cf9e66 39b2e24 8199533 4cf9e66 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 | import os
import time
import requests
import gradio as gr
import openstack
from openstack import exceptions
# --- CONFIGURATION & SHARED STATE ---
active_user_count = 0
is_dekcib_alive = False
clean_link = "149.165.152.222:3000"
full_url = f"http://{clean_link}"
# Styled HTML - Text: "Click here for De-KCIB Copilot"
GREEN_FLASHING_LINK = f"""
<style>
@keyframes flash {{
0% {{ opacity: 1; }}
50% {{ opacity: 0.4; }}
100% {{ opacity: 1; }}
}}
.flashing-btn {{
display: inline-block;
padding: 30px 60px;
font-size: 32px;
font-weight: 900;
text-decoration: none;
color: black !important;
background-color: #39FF14;
border: 6px solid black;
border-radius: 8px;
text-align: center;
animation: flash 1s infinite;
box-shadow: 0 0 30px #39FF14;
transition: transform 0.2s;
}}
.flashing-btn:hover {{
animation: none;
transform: scale(1.05);
opacity: 1;
}}
</style>
<div style="text-align: center; margin: 40px 0;">
<a href="{full_url}" target="_blank" class="flashing-btn">
Click here for De-KCIB Copilot
</a>
</div>
"""
def get_conn():
return openstack.connect(
auth_url=os.getenv("OS_AUTH_URL"),
application_credential_id=os.getenv("OS_APPLICATION_CREDENTIAL_ID"),
application_credential_secret=os.getenv("OS_APPLICATION_CREDENTIAL_SECRET"),
auth_type="v3applicationcredential",
region_name="IU",
interface="public"
)
def get_current_status():
global active_user_count, is_dekcib_alive
try:
conn = get_conn()
instance_id = os.getenv("OS_INSTANCE_ID")
server = conn.compute.find_server(instance_id)
status_text = "β Error: Instance Not Found"
if server:
status_map = {
"ACTIVE": "π’ RUNNING (ACTIVE)",
"SHELVED_OFFLOADED": "π€ SLEEPING (SHELVED)",
"SHUTOFF": "π΄ POWERED OFF",
"BUILD": "π οΈ STARTING...",
"SHELVING": "β³ SAVING STATE..."
}
status_text = status_map.get(server.status, f"β STATE: {server.status}")
if "RUNNING" in status_text:
try:
if requests.get(full_url, timeout=3).status_code < 500:
is_dekcib_alive = True
else:
is_dekcib_alive = False
except:
is_dekcib_alive = False
else:
is_dekcib_alive = False
link_update = gr.update(value=GREEN_FLASHING_LINK if is_dekcib_alive else "", visible=is_dekcib_alive)
return status_text, f"π₯ Space Visitors: {active_user_count}", link_update
except Exception as e:
return f"β Connection Error: {str(e)}", f"π₯ Space Visitors: {active_user_count}", gr.update()
def user_joined():
global active_user_count
active_user_count += 1
return f"π₯ Space Visitors: {active_user_count}"
def user_left():
global active_user_count
active_user_count = max(0, active_user_count - 1)
def manage_instance():
global is_dekcib_alive
try:
conn = get_conn()
instance_id = os.getenv("OS_INSTANCE_ID")
server = conn.compute.find_server(instance_id)
if not server:
yield ("β Error: Instance ID not found in Jetstream2", gr.update(visible=False))
return
if server.status != "ACTIVE":
yield ("β³ Milestone 1/3: Un-shelving De-KCIB...", gr.update(visible=False))
if server.status == "SHELVED_OFFLOADED":
conn.compute.unshelve_server(server)
conn.compute.wait_for_server(server, status='ACTIVE', wait=600)
yield ("β
Milestone 2/3: VM is ACTIVE. Starting software...", gr.update(visible=False))
yield ("π Milestone 3/3: Connecting to De-KCIB Frontend...", gr.update(visible=False))
for i in range(30):
try:
if requests.get(full_url, timeout=3).status_code < 500:
is_dekcib_alive = True
yield ("π Success! De-KCIB is ready for use.", gr.update(value=GREEN_FLASHING_LINK, visible=True))
return
except: pass
yield (f"π Milestone 3/3: Software booting ({i+1}/30)...", gr.update(visible=False))
time.sleep(5)
except Exception as e:
yield (f"β Error during activation: {str(e)}", gr.update(visible=False))
combined_js = """
<script>
let idleTime = 0;
const MAX_IDLE = 10;
function playNotification(status) {
if (status.includes("RUNNING")) {
var audio = new Audio('https://cdn.freesound.org');
audio.play().catch(e => console.log("Audio blocked."));
}
}
function resetTimer() { idleTime = 0; }
window.onmousemove = resetTimer; window.onmousedown = resetTimer; window.onclick = resetTimer; window.onkeypress = resetTimer;
setInterval(function() {
idleTime++;
if (idleTime >= MAX_IDLE) {
alert("Space session expired due to inactivity. Reloading...");
window.location.reload();
}
}, 60000);
</script>
"""
with gr.Blocks(title="De-KCIB Access Portal") as demo:
gr.HTML(combined_js)
session_tracker = gr.State(value="active", delete_callback=user_left)
gr.HTML("<h1 style='font-size: 42px; text-align: center;'>De-KCIB (Deep Knowledge Center for Injury Biomechanics)</h1>")
gr.HTML("<h3 style='font-size: 24px; text-align: center;'>Biomechanics Knowledge-based Conversational Agent by Innovision</h3>")
with gr.Row():
live_status = gr.Textbox(label="Jetstream2 Instance Status", interactive=False)
user_display = gr.Textbox(label="Active Space Visitors", interactive=False)
with gr.Row():
activate_btn = gr.Button("π Activate / Wake Up De-KCIB", variant="primary")
refresh_btn = gr.Button("π Refresh Status", variant="secondary")
status_label = gr.Label(value="Ready")
link_box = gr.HTML(visible=False)
gr.Markdown("---")
gr.Markdown("<center><h3>π Instructions</h3></center>")
gr.Markdown("""
**Access or Wake Up**
- If a flashing **Green Button** is already visible (above these instructions), simply click it to open De-KCIB Copilot.
- If no flashing green button is visible, click **Activate / Wake Up De-KCIB** button (top left). This will trigger the un-shelving process, which may take up to 2+ mins.
**Note A: Track Milestones**
When you click on wake-up, the control panel will cycle through three milestones: Un-shelving, VM Activation, and Software Booting. Please wait(1-2 mins) while the cloud prepares your environment.
**Note B: Automatic Session Timeout**
If you do not interact with this page(or next page - De-KCIB Copilot interface) for **10 minutes**, your session will expire.
**Note C: What to do after clicking on flashing green button**
Once you sign-up using your email on De-KCIB Copilot page (next page), a button will pop-up showing that you need to confirm email. You can safely ignore this step(no need to open your inbox) and continue with login using information you just used for sign-up. Gmail/Microsoft 3rd party sign-up may not work for some users.
""")
gr.Markdown("---")
# Updated footer with LinkedIn hyperlink for Dr. Bentley
gr.HTML("<center><h4>Supporters & Collaborators: (Special thanks to <a href='https://www.linkedin.com/in/timothy-bentley-34423032/' target='_blank'>Dr. Timothy Bentley</a>)</h4></center>")
with gr.Row():
gr.Image("logo1.png", show_label=False, interactive=False, container=False, scale=1)
gr.Image("logo2.png", show_label=False, interactive=False, container=False, scale=1)
gr.Image("logo3.png", show_label=False, interactive=False, container=False, scale=1)
# Logic
demo.load(fn=user_joined, outputs=user_display)
demo.load(fn=get_current_status, outputs=[live_status, user_display, link_box])
status_timer = gr.Timer(5)
status_timer.tick(fn=get_current_status, outputs=[live_status, user_display, link_box])
live_status.change(None, inputs=live_status, js="(s) => playNotification(s)")
activate_btn.click(fn=manage_instance, outputs=[status_label, link_box])
refresh_btn.click(fn=get_current_status, outputs=[live_status, user_display, link_box])
demo.queue().launch()
|