朱东升 commited on
Commit
621bc72
·
1 Parent(s): bef3e47
Files changed (1) hide show
  1. app.py +355 -215
app.py CHANGED
@@ -3,10 +3,10 @@ import json
3
  import importlib
4
  import os
5
  import sys
 
6
  from pathlib import Path
7
  import concurrent.futures
8
  import multiprocessing
9
- import time
10
  import threading
11
  import queue
12
  from datetime import datetime, timedelta
@@ -20,6 +20,118 @@ if current_dir not in sys.path:
20
  if src_dir not in sys.path:
21
  sys.path.append(src_dir)
22
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
  def evaluate(input_data):
24
  """评估代码的主函数
25
 
@@ -79,7 +191,7 @@ def evaluate_single_case(input_data):
79
  results.append(result)
80
 
81
  return results[0]
82
-
83
  except Exception as e:
84
  return {"status": "Exception", "error": str(e)}
85
 
@@ -101,242 +213,270 @@ def evaluate_code(code, language):
101
  except Exception as e:
102
  return {"status": "Exception", "error": str(e)}
103
 
104
- # 创建任务队列和相关变量
105
- task_queue = queue.Queue()
106
- tasks_info = []
107
- tasks_lock = threading.Lock()
108
- total_tasks_count = 0
109
- completed_tasks_count = 0
110
- estimated_completion_time = None
111
- average_task_time = 5 # 默认平均任务时间(秒)
112
-
113
- def add_task(input_data):
114
- """添加任务到队列
115
 
116
- Args:
117
- input_data: 任务数据
118
-
119
  Returns:
120
- dict: 包含任务ID和状态的字典
121
  """
122
- global total_tasks_count, tasks_info
123
-
124
- try:
125
- if not isinstance(input_data, list):
126
- return {"status": "错误", "message": "输入必须是列表格式"}
127
 
128
- task_id = int(time.time() * 1000) # 使用时间戳作为任务ID
129
- task_count = len(input_data)
 
 
 
130
 
131
- with tasks_lock:
132
- for item in input_data:
133
- task_queue.put((task_id, item))
134
- total_tasks_count += 1
135
-
136
- # 更新任务信息
137
- task_info = {
138
- "id": task_id,
139
- "count": task_count,
140
- "status": "等待中",
141
- "submit_time": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
142
- "completed": 0
143
- }
144
- tasks_info.append(task_info)
145
-
146
- # 更新预计完成时间
147
- update_estimated_completion_time()
148
 
149
- return {"status": "成功", "task_id": task_id, "message": f"已添加{task_count}个任务到队列"}
150
-
151
- except Exception as e:
152
- return {"status": "错误", "message": str(e)}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
153
 
154
- def update_estimated_completion_time():
155
- """更新预计完成时间"""
156
- global estimated_completion_time, average_task_time
157
-
158
- remaining_tasks = total_tasks_count - completed_tasks_count
159
- if remaining_tasks > 0:
160
- # 计算预计完成时间
161
- estimated_seconds = remaining_tasks * average_task_time
162
- estimated_completion_time = datetime.now() + timedelta(seconds=estimated_seconds)
163
- else:
164
- estimated_completion_time = None
165
-
166
- def process_tasks():
167
- """处理队列中的任务"""
168
- global completed_tasks_count, average_task_time, tasks_info
169
-
170
- while True:
171
- try:
172
- if not task_queue.empty():
173
- start_time = time.time()
174
-
175
- # 获取任务并处理
176
- task_id, task_data = task_queue.get()
177
- result = evaluate_single_case(task_data)
178
-
179
- # 更新任务状态
180
- with tasks_lock:
181
- completed_tasks_count += 1
182
-
183
- # 更新平均任务时间(使用移动平均)
184
- task_time = time.time() - start_time
185
- average_task_time = (average_task_time * 0.9) + (task_time * 0.1)
186
-
187
- # 更新任务信息
188
- for task in tasks_info:
189
- if task["id"] == task_id:
190
- task["completed"] += 1
191
- if task["completed"] >= task["count"]:
192
- task["status"] = "已完成"
193
- break
194
-
195
- # 更新预计完成时间
196
- update_estimated_completion_time()
197
-
198
- task_queue.task_done()
199
- else:
200
- time.sleep(0.1)
201
- except Exception as e:
202
- print(f"处理任务时出错: {str(e)}")
203
- time.sleep(1)
204
-
205
- # 启动任务处理线程
206
- for _ in range(multiprocessing.cpu_count()):
207
- threading.Thread(target=process_tasks, daemon=True).start()
208
-
209
- def get_queue_status():
210
- """获取队列状态
211
 
212
  Returns:
213
- tuple: 包含任务信息、完成进度和预计完成时间的元组
214
  """
215
- with tasks_lock:
216
- # 复制任务信息以避免并发问题
217
- current_tasks = tasks_info.copy()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
218
 
219
- # 计算进度
220
- if total_tasks_count > 0:
221
- progress = completed_tasks_count / total_tasks_count
222
- else:
223
- progress = 0
 
 
224
 
225
- # 格式化预计完成时间
226
- if estimated_completion_time:
227
- eta = estimated_completion_time.strftime("%Y-%m-%d %H:%M:%S")
228
- remaining_seconds = (estimated_completion_time - datetime.now()).total_seconds()
229
-
230
- if remaining_seconds < 60:
231
- eta_text = f"{int(remaining_seconds)}秒后完成"
232
- elif remaining_seconds < 3600:
233
- eta_text = f"{int(remaining_seconds/60)}分钟后完成"
234
- else:
235
- eta_text = f"{int(remaining_seconds/3600)}小时{int((remaining_seconds%3600)/60)}分钟后完成"
236
- else:
237
- eta = "无任务"
238
- eta_text = "无任务"
239
 
240
- return current_tasks, progress, eta, eta_text
241
-
242
- # 创建Gradio界面
243
- with gr.Blocks(title="代码评估服务", theme=gr.themes.Soft(primary_hue="blue")) as demo:
244
- gr.Markdown(
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
245
  """
246
- # 代码评估服务任务队列监控
247
 
248
- 实时监控系统中的任务队列状态和预计完成时间
249
- """
250
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
251
 
252
- with gr.Row():
253
- with gr.Column(scale=2):
254
- # 任务提交区域
255
- with gr.Group():
256
- gr.Markdown("### 提交新任务")
257
- input_json = gr.JSON(label="输入数据(JSON格式列表)")
258
- submit_btn = gr.Button("提交任务", variant="primary")
 
 
 
 
 
 
 
 
 
 
259
 
260
- with gr.Column(scale=3):
261
- # 状态概览区域
262
- with gr.Group():
263
- gr.Markdown("### 队列状态概览")
264
- with gr.Row():
265
- with gr.Column():
266
- total_tasks = gr.Textbox(label="总任务数", value="0")
267
- with gr.Column():
268
- completed = gr.Textbox(label="已完成任务", value="0")
269
- with gr.Column():
270
- remaining = gr.Textbox(label="剩余任务", value="0")
271
-
272
- progress_bar = gr.Slider(minimum=0, maximum=1, value=0, label="完成进度", interactive=False)
273
- eta_display = gr.Textbox(label="预计完成时间", value="无任务")
274
 
275
- # 任务列表区域
276
- with gr.Group():
277
- gr.Markdown("### 任务队列详情")
278
- task_table = gr.Dataframe(
279
- headers=["任务ID", "任务数量", "状态", "提交时间", "已完成/总数"],
280
- datatype=["str", "number", "str", "str", "str"],
281
- row_count=10,
282
- col_count=(5, "fixed"),
283
- interactive=False
284
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
285
 
286
- # 刷新按钮
287
- refresh_btn = gr.Button("刷新状态", variant="secondary")
 
 
 
 
288
 
289
- # 添加任务的处理函数
290
- def handle_submit(input_data):
291
- result = add_task(input_data)
292
- return update_ui_status(), result["message"]
 
 
 
 
 
 
 
 
 
 
293
 
294
- # 更新UI状态的函数
295
- def update_ui_status():
296
- tasks, progress, eta, eta_text = get_queue_status()
297
 
298
- # 准备表格数据
299
- table_data = []
300
- for task in tasks:
301
- table_data.append([
302
- str(task["id"]),
303
- task["count"],
304
- task["status"],
305
- task["submit_time"],
306
- f"{task['completed']}/{task['count']}"
307
- ])
308
 
309
- return (
310
- table_data,
311
- str(total_tasks_count),
312
- str(completed_tasks_count),
313
- str(total_tasks_count - completed_tasks_count),
314
- progress,
315
- eta_text
316
- )
317
-
318
- # 设置事件处理
319
- submit_btn.click(
320
- handle_submit,
321
- inputs=[input_json],
322
- outputs=[task_table, total_tasks, completed, remaining, progress_bar, eta_display, gr.Textbox(visible=False)]
323
- )
324
-
325
- refresh_btn.click(
326
- update_ui_status,
327
- inputs=[],
328
- outputs=[task_table, total_tasks, completed, remaining, progress_bar, eta_display]
329
- )
330
-
331
- # 定时刷新UI
332
- demo.load(update_ui_status, inputs=[], outputs=[task_table, total_tasks, completed, remaining, progress_bar, eta_display])
333
- # 注释掉不兼容的every方法,改用JavaScript实现自动刷新
334
- refresh_interval = gr.Number(value=3, visible=False)
335
- demo.load(lambda: None, None, js="(()=>{setInterval(()=>{document.querySelector('#refresh-btn').click();}, 3000);return [];})")
336
-
337
- # 添加evaluate函数作为API端点
338
- demo.queue()
339
- demo.add_api_route("/evaluate", evaluate, methods=["POST"])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
340
 
341
  if __name__ == "__main__":
 
342
  demo.launch()
 
3
  import importlib
4
  import os
5
  import sys
6
+ import time
7
  from pathlib import Path
8
  import concurrent.futures
9
  import multiprocessing
 
10
  import threading
11
  import queue
12
  from datetime import datetime, timedelta
 
20
  if src_dir not in sys.path:
21
  sys.path.append(src_dir)
22
 
23
+ # 创建全局任务队列和任务状态跟踪
24
+ task_queue = queue.Queue()
25
+ task_results = {}
26
+ active_tasks = {}
27
+ completed_tasks = []
28
+ task_id_counter = 0
29
+ task_lock = threading.Lock()
30
+
31
+ def get_next_task_id():
32
+ global task_id_counter
33
+ with task_lock:
34
+ task_id_counter += 1
35
+ return f"task_{task_id_counter}"
36
+
37
+ def submit_task(input_data):
38
+ """提交任务到队列
39
+
40
+ Args:
41
+ input_data: 列表(批量处理多个测试用例)
42
+
43
+ Returns:
44
+ str: 任务ID
45
+ """
46
+ try:
47
+ if not isinstance(input_data, list):
48
+ return {"status": "error", "message": "Input must be a list"}
49
+
50
+ task_id = get_next_task_id()
51
+ with task_lock:
52
+ estimated_time = estimate_completion_time(input_data)
53
+ task_info = {
54
+ "id": task_id,
55
+ "data": input_data,
56
+ "status": "queued",
57
+ "submitted_at": datetime.now(),
58
+ "estimated_completion_time": estimated_time,
59
+ "items_count": len(input_data)
60
+ }
61
+ active_tasks[task_id] = task_info
62
+ task_queue.put(task_info)
63
+
64
+ # 如果这是第一个任务,启动处理线程
65
+ if len(active_tasks) == 1:
66
+ threading.Thread(target=process_task_queue, daemon=True).start()
67
+
68
+ return {"status": "success", "task_id": task_id}
69
+
70
+ except Exception as e:
71
+ return {"status": "error", "message": str(e)}
72
+
73
+ def estimate_completion_time(input_data):
74
+ """估计完成任务所需的时间
75
+
76
+ Args:
77
+ input_data: 任务数据
78
+
79
+ Returns:
80
+ timedelta: 估计的完成时间
81
+ """
82
+ # 假设每个任务项平均需要2秒处理
83
+ # 这个值可以根据实际情况调整或从历史数据中学习
84
+ avg_time_per_item = 2
85
+ total_items = len(input_data)
86
+
87
+ # 考虑并行处理因素
88
+ cpu_count = multiprocessing.cpu_count()
89
+ parallel_factor = min(cpu_count, total_items)
90
+
91
+ if parallel_factor > 0:
92
+ estimated_seconds = (total_items * avg_time_per_item) / parallel_factor
93
+ return timedelta(seconds=estimated_seconds)
94
+ else:
95
+ return timedelta(seconds=0)
96
+
97
+ def process_task_queue():
98
+ """处理任务队列的后台线程"""
99
+ while True:
100
+ try:
101
+ if task_queue.empty():
102
+ time.sleep(0.5)
103
+ continue
104
+
105
+ task_info = task_queue.get()
106
+ task_id = task_info["id"]
107
+
108
+ # 更新任务状态
109
+ with task_lock:
110
+ active_tasks[task_id]["status"] = "processing"
111
+
112
+ # 处理任务
113
+ result = evaluate(task_info["data"])
114
+
115
+ # 更新任务结果
116
+ with task_lock:
117
+ active_tasks[task_id]["status"] = "completed"
118
+ active_tasks[task_id]["completed_at"] = datetime.now()
119
+ active_tasks[task_id]["result"] = result
120
+
121
+ # 将任务移至已完成列表
122
+ completed_tasks.append(active_tasks[task_id])
123
+ del active_tasks[task_id]
124
+
125
+ # 保留最近的20个已完成任务
126
+ if len(completed_tasks) > 20:
127
+ completed_tasks.pop(0)
128
+
129
+ task_queue.task_done()
130
+
131
+ except Exception as e:
132
+ print(f"Error processing task queue: {str(e)}")
133
+ time.sleep(1)
134
+
135
  def evaluate(input_data):
136
  """评估代码的主函数
137
 
 
191
  results.append(result)
192
 
193
  return results[0]
194
+
195
  except Exception as e:
196
  return {"status": "Exception", "error": str(e)}
197
 
 
213
  except Exception as e:
214
  return {"status": "Exception", "error": str(e)}
215
 
216
+ def get_queue_status():
217
+ """获取当前队列状态
 
 
 
 
 
 
 
 
 
218
 
 
 
 
219
  Returns:
220
+ dict: 包含队列状态的字典
221
  """
222
+ with task_lock:
223
+ queued_tasks = [task for task in active_tasks.values() if task["status"] == "queued"]
224
+ processing_tasks = [task for task in active_tasks.values() if task["status"] == "processing"]
 
 
225
 
226
+ # 计算总的预计完成时间
227
+ total_estimated_time = timedelta(seconds=0)
228
+ for task in active_tasks.values():
229
+ if isinstance(task["estimated_completion_time"], timedelta):
230
+ total_estimated_time += task["estimated_completion_time"]
231
 
232
+ # 计算队列中的项目总数
233
+ total_items = sum(task["items_count"] for task in active_tasks.values())
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
234
 
235
+ return {
236
+ "queued_tasks": len(queued_tasks),
237
+ "processing_tasks": len(processing_tasks),
238
+ "total_tasks": len(active_tasks),
239
+ "total_items": total_items,
240
+ "estimated_completion_time": str(total_estimated_time),
241
+ "active_tasks": [
242
+ {
243
+ "id": task["id"],
244
+ "status": task["status"],
245
+ "items_count": task["items_count"],
246
+ "submitted_at": task["submitted_at"].strftime("%Y-%m-%d %H:%M:%S"),
247
+ "estimated_completion": str(task["estimated_completion_time"])
248
+ } for task in active_tasks.values()
249
+ ],
250
+ "recent_completed": [
251
+ {
252
+ "id": task["id"],
253
+ "items_count": task["items_count"],
254
+ "submitted_at": task["submitted_at"].strftime("%Y-%m-%d %H:%M:%S"),
255
+ "completed_at": task["completed_at"].strftime("%Y-%m-%d %H:%M:%S") if "completed_at" in task else "",
256
+ "duration": str(task["completed_at"] - task["submitted_at"]) if "completed_at" in task else ""
257
+ } for task in completed_tasks[-5:] # 只显示最近5个完成的任务
258
+ ]
259
+ }
260
 
261
+ def render_queue_status():
262
+ """渲染队列状态UI
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
263
 
264
  Returns:
265
+ str: HTML格式的队列状态显示
266
  """
267
+ status = get_queue_status()
268
+
269
+ html = f"""
270
+ <div style="font-family: Arial, sans-serif; max-width: 900px; margin: 0 auto; padding: 20px; background: #f9f9f9; border-radius: 10px; box-shadow: 0 4px 12px rgba(0,0,0,0.1);">
271
+ <div style="display: flex; justify-content: space-between; margin-bottom: 20px;">
272
+ <div style="background: #fff; padding: 15px; border-radius: 8px; width: 30%; box-shadow: 0 2px 6px rgba(0,0,0,0.05);">
273
+ <h3 style="margin: 0 0 10px; color: #444; font-size: 16px;">排队任务</h3>
274
+ <p style="font-size: 28px; font-weight: bold; margin: 0; color: #3498db;">{status['queued_tasks']}</p>
275
+ </div>
276
+ <div style="background: #fff; padding: 15px; border-radius: 8px; width: 30%; box-shadow: 0 2px 6px rgba(0,0,0,0.05);">
277
+ <h3 style="margin: 0 0 10px; color: #444; font-size: 16px;">处理中任务</h3>
278
+ <p style="font-size: 28px; font-weight: bold; margin: 0; color: #e74c3c;">{status['processing_tasks']}</p>
279
+ </div>
280
+ <div style="background: #fff; padding: 15px; border-radius: 8px; width: 30%; box-shadow: 0 2px 6px rgba(0,0,0,0.05);">
281
+ <h3 style="margin: 0 0 10px; color: #444; font-size: 16px;">总项目数</h3>
282
+ <p style="font-size: 28px; font-weight: bold; margin: 0; color: #2ecc71;">{status['total_items']}</p>
283
+ </div>
284
+ </div>
285
 
286
+ <div style="background: #fff; padding: 20px; border-radius: 8px; margin-bottom: 20px; box-shadow: 0 2px 6px rgba(0,0,0,0.05);">
287
+ <h2 style="margin: 0 0 15px; color: #333; font-size: 18px;">预计完成时间</h2>
288
+ <div style="display: flex; align-items: center;">
289
+ <div style="font-size: 24px; font-weight: bold; color: #9b59b6;">{status['estimated_completion_time']}</div>
290
+ <div style="margin-left: 10px; color: #777; font-size: 14px;">(小时:分钟:秒)</div>
291
+ </div>
292
+ </div>
293
 
294
+ <div style="background: #fff; padding: 20px; border-radius: 8px; margin-bottom: 20px; box-shadow: 0 2px 6px rgba(0,0,0,0.05);">
295
+ <h2 style="margin: 0 0 15px; color: #333; font-size: 18px;">活跃任务</h2>
296
+ <table style="width: 100%; border-collapse: collapse;">
297
+ <thead>
298
+ <tr style="background: #f2f2f2;">
299
+ <th style="padding: 12px; text-align: left; border-bottom: 1px solid #ddd;">任务ID</th>
300
+ <th style="padding: 12px; text-align: left; border-bottom: 1px solid #ddd;">状态</th>
301
+ <th style="padding: 12px; text-align: left; border-bottom: 1px solid #ddd;">项目数</th>
302
+ <th style="padding: 12px; text-align: left; border-bottom: 1px solid #ddd;">提交时间</th>
303
+ <th style="padding: 12px; text-align: left; border-bottom: 1px solid #ddd;">预计完成</th>
304
+ </tr>
305
+ </thead>
306
+ <tbody>
307
+ """
308
 
309
+ if status['active_tasks']:
310
+ for task in status['active_tasks']:
311
+ status_color = "#3498db" if task['status'] == "queued" else "#e74c3c"
312
+ html += f"""
313
+ <tr>
314
+ <td style="padding: 12px; border-bottom: 1px solid #eee;">{task['id']}</td>
315
+ <td style="padding: 12px; border-bottom: 1px solid #eee;">
316
+ <span style="padding: 4px 8px; border-radius: 4px; font-size: 12px; background: {status_color}; color: white;">
317
+ {task['status']}
318
+ </span>
319
+ </td>
320
+ <td style="padding: 12px; border-bottom: 1px solid #eee;">{task['items_count']}</td>
321
+ <td style="padding: 12px; border-bottom: 1px solid #eee;">{task['submitted_at']}</td>
322
+ <td style="padding: 12px; border-bottom: 1px solid #eee;">{task['estimated_completion']}</td>
323
+ </tr>
324
+ """
325
+ else:
326
+ html += f"""
327
+ <tr>
328
+ <td colspan="5" style="padding: 15px; text-align: center; color: #777;">当前没有活跃任务</td>
329
+ </tr>
330
  """
 
331
 
332
+ html += """
333
+ </tbody>
334
+ </table>
335
+ </div>
336
+
337
+ <div style="background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 6px rgba(0,0,0,0.05);">
338
+ <h2 style="margin: 0 0 15px; color: #333; font-size: 18px;">最近完成的任务</h2>
339
+ <table style="width: 100%; border-collapse: collapse;">
340
+ <thead>
341
+ <tr style="background: #f2f2f2;">
342
+ <th style="padding: 12px; text-align: left; border-bottom: 1px solid #ddd;">任务ID</th>
343
+ <th style="padding: 12px; text-align: left; border-bottom: 1px solid #ddd;">项目数</th>
344
+ <th style="padding: 12px; text-align: left; border-bottom: 1px solid #ddd;">提交时间</th>
345
+ <th style="padding: 12px; text-align: left; border-bottom: 1px solid #ddd;">完成时间</th>
346
+ <th style="padding: 12px; text-align: left; border-bottom: 1px solid #ddd;">持续时间</th>
347
+ </tr>
348
+ </thead>
349
+ <tbody>
350
+ """
351
 
352
+ if status['recent_completed']:
353
+ for task in status['recent_completed']:
354
+ html += f"""
355
+ <tr>
356
+ <td style="padding: 12px; border-bottom: 1px solid #eee;">{task['id']}</td>
357
+ <td style="padding: 12px; border-bottom: 1px solid #eee;">{task['items_count']}</td>
358
+ <td style="padding: 12px; border-bottom: 1px solid #eee;">{task['submitted_at']}</td>
359
+ <td style="padding: 12px; border-bottom: 1px solid #eee;">{task['completed_at']}</td>
360
+ <td style="padding: 12px; border-bottom: 1px solid #eee;">{task['duration']}</td>
361
+ </tr>
362
+ """
363
+ else:
364
+ html += f"""
365
+ <tr>
366
+ <td colspan="5" style="padding: 15px; text-align: center; color: #777;">暂无已完成任务</td>
367
+ </tr>
368
+ """
369
 
370
+ html += """
371
+ </tbody>
372
+ </table>
373
+ </div>
374
+ </div>
375
+ """
 
 
 
 
 
 
 
 
376
 
377
+ return html
378
+
379
+ def refresh_ui():
380
+ """定期刷新UI函数"""
381
+ return render_queue_status()
382
+
383
+ def submit_json_data(json_data):
384
+ """提交JSON数据处理接口"""
385
+ try:
386
+ # 解析JSON字符串
387
+ if isinstance(json_data, str):
388
+ data = json.loads(json_data)
389
+ else:
390
+ data = json_data
391
+
392
+ result = submit_task(data)
393
+ return json.dumps(result, ensure_ascii=False, indent=2)
394
+ except Exception as e:
395
+ return json.dumps({"status": "error", "message": str(e)}, ensure_ascii=False, indent=2)
396
+
397
+ # 创建Gradio接���
398
+ with gr.Blocks(title="代码评估服务", theme=gr.themes.Soft()) as demo:
399
+ gr.Markdown("""
400
+ # 代码评估服务
401
+ ### 支持多种编程语言的代码评估服务
402
+ """)
403
 
404
+ with gr.Tab("任务队列状态"):
405
+ status_html = gr.HTML(render_queue_status)
406
+ refresh_button = gr.Button("刷新状态")
407
+ refresh_button.click(fn=refresh_ui, outputs=status_html)
408
+ # 设置自动刷新 (5秒一次)
409
+ demo.load(fn=refresh_ui, outputs=status_html, every=5)
410
 
411
+ with gr.Tab("提交新任务"):
412
+ with gr.Row():
413
+ with gr.Column():
414
+ json_input = gr.Textbox(
415
+ label="输入JSON数据",
416
+ placeholder='[{"language": "python", "prompt": "def add(a, b):\\n", "processed_completions": [" return a + b"], "tests": "assert add(1, 2) == 3"}]',
417
+ lines=10
418
+ )
419
+ submit_button = gr.Button("提交任务")
420
+
421
+ with gr.Column():
422
+ result_output = gr.Textbox(label="提交结果", lines=5)
423
+
424
+ submit_button.click(fn=submit_json_data, inputs=json_input, outputs=result_output)
425
 
426
+ with gr.Tab("API文档"):
427
+ gr.Markdown("""
428
+ ## API 文档
429
 
430
+ ### 1. 提交任务
 
 
 
 
 
 
 
 
 
431
 
432
+ **请求:**
433
+
434
+ ```
435
+ POST /api/predict
436
+ Content-Type: application/json
437
+
438
+ [
439
+ {
440
+ "language": "python",
441
+ "prompt": "def add(a, b):\\n",
442
+ "processed_completions": [" return a + b"],
443
+ "tests": "assert add(1, 2) == 3"
444
+ }
445
+ ]
446
+ ```
447
+
448
+ **响应:**
449
+
450
+ ```json
451
+ {
452
+ "status": "success",
453
+ "task_id": "task_1"
454
+ }
455
+ ```
456
+
457
+ ### 2. 查询任务状态
458
+
459
+ **请求:**
460
+
461
+ ```
462
+ GET /api/status
463
+ ```
464
+
465
+ **响应:**
466
+
467
+ ```json
468
+ {
469
+ "queued_tasks": 1,
470
+ "processing_tasks": 2,
471
+ "total_tasks": 3,
472
+ "total_items": 15,
473
+ "estimated_completion_time": "0:05:30",
474
+ "active_tasks": [...],
475
+ "recent_completed": [...]
476
+ }
477
+ ```
478
+ """)
479
 
480
  if __name__ == "__main__":
481
+ demo.queue()
482
  demo.launch()