feat: setup dataset enrichment app codebase and scripts

This commit is contained in:
asus committed 2026-08-05 11:52:27 +07:00
1 parent b5c28cc98a
commit d07578462e
72 files changed
+11370

No files matched your search

+91
View File
@@ -0,0 +1,91 @@
"""Annotation and review-state routes (REQ-040…045)."""
from typing import Any, Dict, List, Optional
from fastapi import APIRouter, HTTPException
from pydantic import BaseModel
from backend import batches as batch_store
from backend import review as review_store
router = APIRouter(tags=["review"])
class AnnotationRequest(BaseModel):
class_id: int = 0
geometry: Dict[str, Any]
class AnnotationPatch(BaseModel):
class_id: Optional[int] = None
geometry: Optional[Dict[str, Any]] = None
class StatusRequest(BaseModel):
status: str
class AssistRequest(BaseModel):
box: List[float]
class_id: int = 0
threshold: float = 0.5
@router.get("/api/frames/{frame_id}/annotations")
def list_annotations(frame_id: int) -> dict:
target = review_store.frame(frame_id)
if target is None:
raise HTTPException(404, "No such frame")
return {
"frame": {
"id": target["id"], "batch_id": target["batch_id"], "idx": target["idx"],
"width": target["width"], "height": target["height"],
"review_status": target["review_status"], "label_type": target["label_type"],
},
"annotations": review_store.listing(frame_id),
}
@router.post("/api/frames/{frame_id}/annotations")
def add_annotation(frame_id: int, request: AnnotationRequest) -> dict:
try:
return review_store.add(frame_id, request.class_id, request.geometry)
except review_store.ReviewError as exc:
raise HTTPException(400, str(exc))
@router.patch("/api/annotations/{annotation_id}")
def patch_annotation(annotation_id: int, request: AnnotationPatch) -> dict:
try:
return review_store.update(annotation_id, request.class_id, request.geometry)
except review_store.ReviewError as exc:
raise HTTPException(400, str(exc))
@router.delete("/api/annotations/{annotation_id}")
def delete_annotation(annotation_id: int) -> dict:
return {"deleted": review_store.delete(annotation_id)}
@router.post("/api/frames/{frame_id}/assist")
def assist(frame_id: int, request: AssistRequest) -> dict:
try:
return review_store.assist(frame_id, request.box, request.class_id,
request.threshold)
except review_store.ReviewError as exc:
raise HTTPException(400, str(exc))
@router.post("/api/frames/{frame_id}/status")
def set_status(frame_id: int, request: StatusRequest) -> dict:
try:
return review_store.set_status(frame_id, request.status)
except review_store.ReviewError as exc:
raise HTTPException(400, str(exc))
@router.get("/api/batches/{batch_id}/next-pending")
def next_pending(batch_id: int, after_idx: int = -1) -> dict:
if batch_store.get(batch_id) is None:
raise HTTPException(404, "No such batch")
return {"frame_id": review_store.next_pending(batch_id, after_idx)}