Spaces:
Sleeping
Sleeping
朱东升
commited on
Commit
·
621bc72
1
Parent(s):
bef3e47
update4
Browse files
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 |
-
|
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:
|
121 |
"""
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
if not isinstance(input_data, list):
|
126 |
-
return {"status": "错误", "message": "输入必须是列表格式"}
|
127 |
|
128 |
-
|
129 |
-
|
|
|
|
|
|
|
130 |
|
131 |
-
|
132 |
-
|
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 {
|
150 |
-
|
151 |
-
|
152 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
153 |
|
154 |
-
def
|
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 |
-
|
214 |
"""
|
215 |
-
|
216 |
-
|
217 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
218 |
|
219 |
-
#
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
|
|
|
|
224 |
|
225 |
-
#
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
|
240 |
-
|
241 |
-
|
242 |
-
#
|
243 |
-
|
244 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
245 |
"""
|
246 |
-
# 代码评估服务任务队列监控
|
247 |
|
248 |
-
|
249 |
-
|
250 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
251 |
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
259 |
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
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 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
285 |
|
286 |
-
|
287 |
-
|
|
|
|
|
|
|
|
|
288 |
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
293 |
|
294 |
-
|
295 |
-
|
296 |
-
|
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 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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()
|