File size: 2,076 Bytes
4a3fec4
 
 
 
 
 
 
 
 
 
 
952b23c
4a3fec4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
"""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