Spaces:
Sleeping
Sleeping
| """Pydantic models for the FROZEN inference response contract. Phase 5. | |
| These mirror frontend/lib/types.ts exactly — the field names/shape are the integration | |
| seam (Phase 6 mocks it, Phase 5 fills it). Do not rename fields without changing both. | |
| """ | |
| from __future__ import annotations | |
| from typing import Literal, Optional | |
| from pydantic import BaseModel, Field | |
| CoralClass = Literal["healthy", "bleached"] | |
| JobStatus = Literal["queued", "processing", "complete", "failed"] | |
| class Segment(BaseModel): | |
| segment_id: int | |
| mask_area_px: int | |
| bbox: list[int] # [x0, y0, x1, y1] in source-image px | |
| predicted_class: CoralClass | |
| prediction_set: list[CoralClass] | |
| prediction_set_size: int | |
| confidence_scores: dict[str, float] # {"healthy": .., "bleached": ..} | |
| coverage_pct: float | |
| class AreaWeighted(BaseModel): | |
| healthy_pct: float | |
| bleached_pct: float | |
| class Summary(BaseModel): | |
| total_segments: int | |
| area_weighted: AreaWeighted | |
| uncertain_segments: int | |
| dominant_status: CoralClass | |
| class InferenceResponse(BaseModel): | |
| """Returned by GET /infer/{job_id}. When status != 'complete', segments/summary are | |
| empty/None and the client keeps polling.""" | |
| job_id: str | |
| status: JobStatus | |
| processing_time_ms: int = 0 | |
| image_url: str = "" | |
| model_version: str = "" | |
| image_width: Optional[int] = None | |
| image_height: Optional[int] = None | |
| segments: list[Segment] = Field(default_factory=list) | |
| summary: Optional[Summary] = None | |
| error_message: Optional[str] = None | |
| class SubmitResponse(BaseModel): | |
| """Returned by POST /infer — the async enqueue ack.""" | |
| job_id: str | |
| status: JobStatus = "queued" | |
| class HealthResponse(BaseModel): | |
| status: str | |
| models_loaded: bool | |
| stub_mode: bool | |
| model_version: str | |
| last_inference_latency_ms: Optional[int] = None | |