96 lines
2.4 KiB
Python
96 lines
2.4 KiB
Python
"""
|
|
Event emission helpers for detection pipeline stages.
|
|
|
|
Single place that knows how to build event payloads.
|
|
Stages call these instead of constructing dicts or dataclasses directly.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import dataclasses
|
|
from datetime import datetime, timezone
|
|
|
|
from detect.events import push_detect_event
|
|
from detect.models import PipelineStats
|
|
|
|
|
|
def log(job_id: str | None, stage: str, level: str, msg: str) -> None:
|
|
"""Emit a log event."""
|
|
if not job_id:
|
|
return
|
|
payload = {
|
|
"level": level,
|
|
"stage": stage,
|
|
"msg": msg,
|
|
"ts": datetime.now(timezone.utc).isoformat(),
|
|
}
|
|
push_detect_event(job_id, "log", payload)
|
|
|
|
|
|
def stats(job_id: str | None, **kwargs) -> None:
|
|
"""Emit a stats_update event. Pass only the fields that changed."""
|
|
if not job_id:
|
|
return
|
|
s = PipelineStats(**kwargs)
|
|
push_detect_event(job_id, "stats_update", dataclasses.asdict(s))
|
|
|
|
|
|
def frame_update(
|
|
job_id: str | None,
|
|
frame_ref: int,
|
|
timestamp: float,
|
|
jpeg_b64: str,
|
|
boxes: list[dict],
|
|
) -> None:
|
|
"""Emit a frame_update event with the image and bounding boxes."""
|
|
if not job_id:
|
|
return
|
|
payload = {
|
|
"frame_ref": frame_ref,
|
|
"timestamp": timestamp,
|
|
"jpeg_b64": jpeg_b64,
|
|
"boxes": boxes,
|
|
}
|
|
push_detect_event(job_id, "frame_update", payload)
|
|
|
|
|
|
def graph_update(job_id: str | None, nodes: list[dict]) -> None:
|
|
"""Emit a graph_update event with node states."""
|
|
if not job_id:
|
|
return
|
|
payload = {"nodes": nodes}
|
|
push_detect_event(job_id, "graph_update", payload)
|
|
|
|
|
|
def detection(
|
|
job_id: str | None,
|
|
brand: str,
|
|
confidence: float,
|
|
source: str,
|
|
timestamp: float,
|
|
duration: float = 0.0,
|
|
content_type: str = "",
|
|
frame_ref: int | None = None,
|
|
) -> None:
|
|
"""Emit a brand detection event."""
|
|
if not job_id:
|
|
return
|
|
payload = {
|
|
"brand": brand,
|
|
"confidence": confidence,
|
|
"source": source,
|
|
"timestamp": timestamp,
|
|
"duration": duration,
|
|
"content_type": content_type,
|
|
"frame_ref": frame_ref,
|
|
}
|
|
push_detect_event(job_id, "detection", payload)
|
|
|
|
|
|
def job_complete(job_id: str | None, report: dict) -> None:
|
|
"""Emit a job_complete event with the final report."""
|
|
if not job_id:
|
|
return
|
|
payload = {"job_id": job_id, "report": report}
|
|
push_detect_event(job_id, "job_complete", payload)
|