| from __future__ import annotations | |
| from typing import Any, Literal | |
| from pydantic import BaseModel, Field | |
| class Detection(BaseModel): | |
| frame_index: int = Field(ge=0) | |
| timestamp_sec: float = Field(ge=0.0) | |
| label: str | |
| confidence: float = Field(ge=0.0, le=1.0) | |
| bbox_xyxy: tuple[float, float, float, float] | |
| bbox_xyxy_norm: tuple[float, float, float, float] | |
| track_id: int | None = None | |
| class FrameSample(BaseModel): | |
| frame_index: int = Field(ge=0) | |
| timestamp_sec: float = Field(ge=0.0) | |
| class VideoProcessResult(BaseModel): | |
| output_video_path: str | |
| classes: list[str] | |
| detections: list[Detection] | |
| frames: list[FrameSample] = Field(default_factory=list) | |
| processed_frames: int | |
| source_fps: float | |
| output_fps: float | |
| frame_stride: int | |
| sample_interval_sec: float | None = None | |
| class ActionEvent(BaseModel): | |
| rule: str | |
| action: str | |
| type: Literal["simulate", "webhook"] | |
| frame_index: int | |
| timestamp_sec: float | |
| status: str = "pending" | |
| url: str | None = None | |
| payload: dict[str, Any] = Field(default_factory=dict) | |
| response_status: int | None = None | |
| error: str | None = None | |