observations.py 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. import json
  2. from fastapi import APIRouter, File, Form, HTTPException, UploadFile, status
  3. from app.schemas.common import ListResponse
  4. from app.schemas.observation import ObservationCreateRequest, ObservationSummary
  5. from app.services.observation_service import ObservationService
  6. router = APIRouter()
  7. service = ObservationService()
  8. @router.post(
  9. "",
  10. response_model=ObservationSummary,
  11. status_code=status.HTTP_201_CREATED,
  12. )
  13. def create_observation(payload: ObservationCreateRequest) -> ObservationSummary:
  14. return service.create_observation(payload)
  15. @router.post(
  16. "/upload",
  17. response_model=ObservationSummary,
  18. status_code=status.HTTP_201_CREATED,
  19. )
  20. async def upload_observation(
  21. audio_file: UploadFile = File(...),
  22. duration_ms: int = Form(...),
  23. sample_rate: int = Form(...),
  24. channels: int = Form(...),
  25. tags_json: str = Form(default="[]"),
  26. capture_metadata_json: str = Form(default="{}"),
  27. ) -> ObservationSummary:
  28. try:
  29. tags = json.loads(tags_json)
  30. capture_metadata = json.loads(capture_metadata_json)
  31. except json.JSONDecodeError as error:
  32. raise HTTPException(
  33. status_code=status.HTTP_400_BAD_REQUEST,
  34. detail=f"Invalid JSON form payload: {error}",
  35. ) from error
  36. content = await audio_file.read()
  37. if not content:
  38. raise HTTPException(
  39. status_code=status.HTTP_400_BAD_REQUEST,
  40. detail="Uploaded file is empty.",
  41. )
  42. return service.create_observation_from_upload(
  43. filename=audio_file.filename or "capture.bin",
  44. content=content,
  45. duration_ms=duration_ms,
  46. sample_rate=sample_rate,
  47. channels=channels,
  48. tags=tags,
  49. capture_metadata=capture_metadata,
  50. )
  51. @router.get("", response_model=ListResponse[ObservationSummary])
  52. def list_observations() -> ListResponse[ObservationSummary]:
  53. return service.list_observations()
  54. @router.get("/{observation_id}", response_model=ObservationSummary)
  55. def get_observation(observation_id: str) -> ObservationSummary:
  56. observation = service.get_observation(observation_id)
  57. if observation is None:
  58. raise HTTPException(
  59. status_code=status.HTTP_404_NOT_FOUND,
  60. detail=f"Observation '{observation_id}' was not found.",
  61. )
  62. return observation