This commit is contained in:
2026-03-27 00:01:54 -03:00
parent 65814b5b9e
commit df6bcb01e8
14 changed files with 1246 additions and 203 deletions

View File

@@ -116,6 +116,65 @@ def list_checkpoints(job_id: str) -> list[CheckpointInfo]:
return result
class CheckpointFrameInfo(BaseModel):
seq: int
timestamp: float
jpeg_b64: str
class CheckpointData(BaseModel):
job_id: str
stage: str
profile_name: str
video_path: str
is_scenario: bool
scenario_label: str
frames: list[CheckpointFrameInfo]
stats: dict = {}
config_snapshot: dict = {}
stage_output_key: str = ""
@router.get("/checkpoints/{job_id}/{stage}", response_model=CheckpointData)
def get_checkpoint_data(job_id: str, stage: str):
"""Load checkpoint frames + metadata for the editor UI."""
from core.db.detect import get_stage_checkpoint
from detect.checkpoint.frames import load_frames_b64
checkpoint = get_stage_checkpoint(job_id, stage)
if not checkpoint:
raise HTTPException(status_code=404, detail=f"No checkpoint for {job_id}/{stage}")
raw_manifest = checkpoint.frames_manifest or {}
manifest = {int(k): v for k, v in raw_manifest.items()}
frame_metadata = checkpoint.frames_meta or []
# Only load filtered frames if available, otherwise all
filtered = set(checkpoint.filtered_frame_sequences or [])
if filtered:
manifest = {k: v for k, v in manifest.items() if k in filtered}
frames_b64 = load_frames_b64(manifest, frame_metadata)
frame_list = [
CheckpointFrameInfo(seq=f["seq"], timestamp=f["timestamp"], jpeg_b64=f["jpeg_b64"])
for f in frames_b64
]
return CheckpointData(
job_id=str(checkpoint.job_id),
stage=checkpoint.stage,
profile_name=checkpoint.profile_name,
video_path=checkpoint.video_path,
is_scenario=checkpoint.is_scenario,
scenario_label=checkpoint.scenario_label,
frames=frame_list,
stats=checkpoint.stats or {},
config_snapshot=checkpoint.config_snapshot or {},
stage_output_key=checkpoint.stage_output_key or "",
)
@router.get("/scenarios", response_model=list[ScenarioInfo])
def list_scenarios_endpoint():
"""List all available scenarios (bookmarked checkpoints)."""

View File

@@ -110,7 +110,7 @@ class StageCheckpoint:
# Scenario — a checkpoint bookmarked for the editor workflow.
# Created by seeders (manual scripts that populate state from real footage)
# or captured from a running pipeline. Loaded via URL:
# /detection/?job=<job_id>&stage=<stage>&editor=true
# /detection/?job=<job_id>#/editor/<stage>
is_scenario: bool = False
scenario_label: str = "" # human-readable name, e.g. "chelsea_edges_lowcanny"