import json from fastapi import APIRouter, File, Form, HTTPException, UploadFile, status from app.schemas.common import ListResponse from app.schemas.observation import ObservationCreateRequest, ObservationSummary from app.services.observation_service import ObservationService router = APIRouter() service = ObservationService() @router.post( "", response_model=ObservationSummary, status_code=status.HTTP_201_CREATED, ) def create_observation(payload: ObservationCreateRequest) -> ObservationSummary: return service.create_observation(payload) @router.post( "/upload", response_model=ObservationSummary, status_code=status.HTTP_201_CREATED, ) async def upload_observation( audio_file: UploadFile = File(...), duration_ms: int = Form(...), sample_rate: int = Form(...), channels: int = Form(...), tags_json: str = Form(default="[]"), capture_metadata_json: str = Form(default="{}"), ) -> ObservationSummary: try: tags = json.loads(tags_json) capture_metadata = json.loads(capture_metadata_json) except json.JSONDecodeError as error: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail=f"Invalid JSON form payload: {error}", ) from error content = await audio_file.read() if not content: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="Uploaded file is empty.", ) return service.create_observation_from_upload( filename=audio_file.filename or "capture.bin", content=content, duration_ms=duration_ms, sample_rate=sample_rate, channels=channels, tags=tags, capture_metadata=capture_metadata, ) @router.get("", response_model=ListResponse[ObservationSummary]) def list_observations() -> ListResponse[ObservationSummary]: return service.list_observations() @router.get("/{observation_id}", response_model=ObservationSummary) def get_observation(observation_id: str) -> ObservationSummary: observation = service.get_observation(observation_id) if observation is None: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail=f"Observation '{observation_id}' was not found.", ) return observation