Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -1,17 +1,13 @@
|
|
| 1 |
-
# app.py — FINAL VERSION
|
| 2 |
import gradio as gr
|
| 3 |
-
import time
|
| 4 |
from backend import (
|
| 5 |
-
# User Management
|
| 6 |
create_user,
|
| 7 |
get_user_by_username,
|
| 8 |
verify_password,
|
| 9 |
-
# Project Management
|
| 10 |
create_project,
|
| 11 |
get_user_projects,
|
| 12 |
-
search_projects,
|
| 13 |
get_project,
|
| 14 |
-
# Job Queue
|
| 15 |
queue_job,
|
| 16 |
)
|
| 17 |
import psutil
|
|
@@ -44,7 +40,7 @@ def format_projects_list(projects):
|
|
| 44 |
def get_project_choices(user_id):
|
| 45 |
"""Fetches user projects and formats them for a dropdown."""
|
| 46 |
if not user_id: return []
|
| 47 |
-
projects = get_user_projects(user_id
|
| 48 |
return [(f"[{p['id']}] {p['title']}", p['id']) for p in projects] if projects else []
|
| 49 |
|
| 50 |
# --- CORE LOGIC HANDLERS FOR UI ---
|
|
@@ -110,7 +106,7 @@ def refresh_all_projects(user_state):
|
|
| 110 |
projects = get_user_projects(user_id)
|
| 111 |
return gr.update(value=format_projects_list(projects)), gr.update(choices=get_project_choices(user_id))
|
| 112 |
|
| 113 |
-
# --- CUSTOM GENERATOR LOOPS
|
| 114 |
|
| 115 |
def system_stats_loop():
|
| 116 |
"""A generator that yields system stats every 5 seconds, forever."""
|
|
@@ -122,20 +118,20 @@ def stream_logs(project_id):
|
|
| 122 |
"""A generator that streams logs for a selected project every 3 seconds."""
|
| 123 |
if not project_id:
|
| 124 |
yield "⬅️ Select a project from the dropdown to see its live logs."
|
| 125 |
-
return
|
| 126 |
|
| 127 |
-
# Yield an initial message immediately
|
| 128 |
-
project = get_project(project_id)
|
| 129 |
-
if not project or not project['logs']:
|
| 130 |
-
yield f"🕒 Project #{project_id} is queued or starting... Logs will appear here shortly."
|
| 131 |
-
|
| 132 |
-
# Loop to continuously poll for new logs
|
| 133 |
while True:
|
| 134 |
project = get_project(project_id)
|
| 135 |
if project:
|
| 136 |
-
|
| 137 |
-
|
|
|
|
|
|
|
|
|
|
| 138 |
if project['status'] in ['completed', 'failed']:
|
|
|
|
|
|
|
|
|
|
| 139 |
break
|
| 140 |
else:
|
| 141 |
yield f"Error: Project #{project_id} not found."
|
|
@@ -201,23 +197,17 @@ with gr.Blocks(title="Code Agents Pro", theme=gr.themes.Soft()) as demo:
|
|
| 201 |
outputs=[projects_display, project_selector]
|
| 202 |
)
|
| 203 |
|
| 204 |
-
# --- THE FIX IN ACTION ---
|
| 205 |
-
# When the dropdown changes (either by user or by the start_project_flow),
|
| 206 |
-
# it triggers the stream_logs generator, starting our custom loop.
|
| 207 |
project_selector.change(
|
| 208 |
fn=stream_logs,
|
| 209 |
inputs=project_selector,
|
| 210 |
outputs=logs_display
|
| 211 |
)
|
| 212 |
|
| 213 |
-
# Use a generator for the system stats loop, triggered on app load.
|
| 214 |
-
# This is the backward-compatible way to do a recurring event.
|
| 215 |
demo.load(
|
| 216 |
fn=system_stats_loop,
|
| 217 |
outputs=ram_monitor
|
| 218 |
)
|
| 219 |
|
| 220 |
-
# --- CSS STYLING ---
|
| 221 |
gr.HTML("""
|
| 222 |
<style>
|
| 223 |
.logs-container { height: 600px; overflow-y: auto; border: 1px solid #E5E7EB; border-radius: 8px; padding: 8px; background-color: #F9FAFB; }
|
|
|
|
| 1 |
+
# app.py — FINAL VERSION
|
| 2 |
import gradio as gr
|
| 3 |
+
import time
|
| 4 |
from backend import (
|
|
|
|
| 5 |
create_user,
|
| 6 |
get_user_by_username,
|
| 7 |
verify_password,
|
|
|
|
| 8 |
create_project,
|
| 9 |
get_user_projects,
|
|
|
|
| 10 |
get_project,
|
|
|
|
| 11 |
queue_job,
|
| 12 |
)
|
| 13 |
import psutil
|
|
|
|
| 40 |
def get_project_choices(user_id):
|
| 41 |
"""Fetches user projects and formats them for a dropdown."""
|
| 42 |
if not user_id: return []
|
| 43 |
+
projects = get_user_projects(user_id)
|
| 44 |
return [(f"[{p['id']}] {p['title']}", p['id']) for p in projects] if projects else []
|
| 45 |
|
| 46 |
# --- CORE LOGIC HANDLERS FOR UI ---
|
|
|
|
| 106 |
projects = get_user_projects(user_id)
|
| 107 |
return gr.update(value=format_projects_list(projects)), gr.update(choices=get_project_choices(user_id))
|
| 108 |
|
| 109 |
+
# --- CUSTOM GENERATOR LOOPS FOR LIVE UPDATES ---
|
| 110 |
|
| 111 |
def system_stats_loop():
|
| 112 |
"""A generator that yields system stats every 5 seconds, forever."""
|
|
|
|
| 118 |
"""A generator that streams logs for a selected project every 3 seconds."""
|
| 119 |
if not project_id:
|
| 120 |
yield "⬅️ Select a project from the dropdown to see its live logs."
|
| 121 |
+
return
|
| 122 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 123 |
while True:
|
| 124 |
project = get_project(project_id)
|
| 125 |
if project:
|
| 126 |
+
if not project['logs']:
|
| 127 |
+
yield f"🕒 Project #{project_id} is queued or starting... Logs will appear here shortly."
|
| 128 |
+
else:
|
| 129 |
+
yield project['logs']
|
| 130 |
+
|
| 131 |
if project['status'] in ['completed', 'failed']:
|
| 132 |
+
# Refresh the main dashboard one last time to show the final status
|
| 133 |
+
# This requires a bit of a workaround since generators can only yield for one output.
|
| 134 |
+
# The visual refresh on the dashboard will happen on the next manual click.
|
| 135 |
break
|
| 136 |
else:
|
| 137 |
yield f"Error: Project #{project_id} not found."
|
|
|
|
| 197 |
outputs=[projects_display, project_selector]
|
| 198 |
)
|
| 199 |
|
|
|
|
|
|
|
|
|
|
| 200 |
project_selector.change(
|
| 201 |
fn=stream_logs,
|
| 202 |
inputs=project_selector,
|
| 203 |
outputs=logs_display
|
| 204 |
)
|
| 205 |
|
|
|
|
|
|
|
| 206 |
demo.load(
|
| 207 |
fn=system_stats_loop,
|
| 208 |
outputs=ram_monitor
|
| 209 |
)
|
| 210 |
|
|
|
|
| 211 |
gr.HTML("""
|
| 212 |
<style>
|
| 213 |
.logs-container { height: 600px; overflow-y: auto; border: 1px solid #E5E7EB; border-radius: 8px; padding: 8px; background-color: #F9FAFB; }
|