decode.py 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. """Formal decode API routes."""
  2. from __future__ import annotations
  3. from typing import Any
  4. from uuid import UUID
  5. from fastapi import APIRouter, Depends, HTTPException
  6. from app.dependencies import get_acquisition_repository, get_decode_repository
  7. from app.schemas import (
  8. CandidateItemSchema,
  9. DecodeResultSchema,
  10. IngestRecordSchema,
  11. KnowledgeParticleSchema,
  12. MediaAssetSchema,
  13. PayloadDraftSchema,
  14. ScopeResultSchema,
  15. )
  16. router = APIRouter(prefix="/api/decode", tags=["decode"])
  17. @router.get("/items/{item_id}/result", response_model=DecodeResultSchema)
  18. def decode_result(
  19. item_id: UUID,
  20. repo: Any = Depends(get_decode_repository),
  21. ) -> DecodeResultSchema:
  22. getter = getattr(repo, "get_decode_result_for_item", None)
  23. if getter is None:
  24. raise HTTPException(status_code=501, detail="decode result reader is not implemented")
  25. return DecodeResultSchema.model_validate(getter(item_id))
  26. @router.get("/items/{item_id}/detail")
  27. def decode_item_detail(
  28. item_id: UUID,
  29. acquisition_repo: Any = Depends(get_acquisition_repository),
  30. decode_repo: Any = Depends(get_decode_repository),
  31. ) -> dict[str, Any]:
  32. try:
  33. item = acquisition_repo.get_candidate_item(item_id)
  34. media = acquisition_repo.list_media_assets_for_item(item_id)
  35. result = decode_repo.get_decode_result_for_item(item_id)
  36. except Exception as exc:
  37. raise HTTPException(status_code=404, detail=f"decode detail not found: {exc}") from exc
  38. list_particles = getattr(decode_repo, "list_knowledge_particles", None)
  39. list_scopes = getattr(decode_repo, "list_scope_results", None)
  40. list_payloads = getattr(decode_repo, "list_payload_drafts", None)
  41. list_ingests = getattr(decode_repo, "list_ingest_records", None)
  42. raw_item = item.model_dump() if hasattr(item, "model_dump") else dict(item)
  43. item_payload = CandidateItemSchema.model_validate(
  44. {
  45. **raw_item,
  46. "media_assets": [
  47. MediaAssetSchema.model_validate(row).model_dump(mode="json")
  48. for row in media
  49. ],
  50. }
  51. ).model_dump(mode="json")
  52. return {
  53. "item": item_payload,
  54. "decode_result": DecodeResultSchema.model_validate(result).model_dump(mode="json"),
  55. "knowledge_particles": [
  56. KnowledgeParticleSchema.model_validate(row).model_dump(mode="json")
  57. for row in (list_particles(item_id=item_id) if list_particles else [])
  58. ],
  59. "scope_results": [
  60. ScopeResultSchema.model_validate(row).model_dump(mode="json")
  61. for row in (list_scopes(item_id=item_id) if list_scopes else [])
  62. ],
  63. "payload_drafts": [
  64. PayloadDraftSchema.model_validate(row).model_dump(mode="json")
  65. for row in (list_payloads(item_id=item_id) if list_payloads else [])
  66. ],
  67. "ingest_records": [
  68. IngestRecordSchema.model_validate(row).model_dump(mode="json")
  69. for row in (list_ingests(item_id=item_id) if list_ingests else [])
  70. ],
  71. }
  72. @router.post("/items/{item_id}/jobs")
  73. def enqueue_decode_job(
  74. item_id: UUID,
  75. repo: Any = Depends(get_decode_repository),
  76. ) -> dict[str, Any]:
  77. create = getattr(repo, "create_decode_job", None)
  78. if create is None:
  79. raise HTTPException(status_code=501, detail="decode job writer is not implemented")
  80. job = create(item_id=item_id, status="pending")
  81. return {"job": job.model_dump(mode="json") if hasattr(job, "model_dump") else job}