openpa / stage_progress.py
fuann's picture
Rename assessment action and stage to Scoring
952b23c verified
Raw History Blame Contribute Delete
2.08 kB
"""Render and stream real assessment stages without estimated percentages."""
import html
from contextvars import copy_context
from queue import Queue
from threading import Thread
def stage_names(mode):
steps = [("audio", "Prepare audio"), ("model", "Prepare model")]
if mode == "Reference-free":
steps.append(("transcribe", "Transcribe speech"))
return steps + [("score", "Scoring")]
def stage_markup(mode, active=None, complete=False, failed=False):
steps = stage_names(mode)
index = next((i for i, (key, _) in enumerate(steps) if key == active), -1)
items = []
for i, (key, label) in enumerate(steps):
state = "done" if complete or 0 <= i < index else "active" if i == index else "pending"
if failed and i == index:
state = "failed"
number = "✓" if state == "done" else str(i + 1)
items.append(f'<div class="assessment-step {state}" data-stage="{key}">'
f'<span class="step-number">{number}</span><span>{label}</span>'
'<div class="step-track"><i></i></div></div>')
caption = "Assessment complete" if complete else "Assessment stopped" if failed else (
f"Stage {index + 1} of {len(steps)} · {steps[index][1]}" if index >= 0 else f"{len(steps)} assessment stages")
return '<div class="assessment-progress" role="status" aria-live="polite"><div class="step-caption">' + html.escape(caption) + '</div><div class="assessment-steps">' + ''.join(items) + '</div></div>'
def stream_work(work):
"""Run blocking inference while forwarding stage transitions to Gradio."""
events = Queue()
def run():
try:
result = work(lambda stage: events.put(("stage", stage)))
events.put(("result", result))
except Exception as error:
events.put(("error", error))
context = copy_context()
Thread(target=lambda: context.run(run), daemon=True).start()
while True:
kind, payload = events.get()
yield kind, payload
if kind != "stage":
return