reefscan-api / backend /schemas.py
HrishiKabra's picture
Upload folder using huggingface_hub
f8dd35f verified
Raw
History Blame Contribute Delete
1.85 kB
"""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