| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124 |
- """Formal acquisition API routes."""
- from __future__ import annotations
- from collections import defaultdict
- from typing import Any
- from uuid import UUID
- from fastapi import APIRouter, Depends
- from acquisition.repositories.base import AcquisitionRepository
- from app.dependencies import get_acquisition_repository
- from app.schemas import (
- AcquisitionRunSummarySchema,
- CandidateItemSchema,
- ItemClassificationSchema,
- MediaAssetSchema,
- QueryBatchSchema,
- QuerySchema,
- )
- router = APIRouter(prefix="/api", tags=["acquisition"])
- def _model_dump(row: Any) -> dict[str, Any]:
- if isinstance(row, dict):
- return dict(row)
- if hasattr(row, "model_dump"):
- return row.model_dump()
- return dict(row)
- def _normalize_query_detail(detail: dict[str, Any]) -> dict[str, Any]:
- media_by_item: dict[Any, list[dict[str, Any]]] = defaultdict(list)
- for media in detail.get("media_assets") or []:
- media_by_item[media["item_id"]].append(media)
- classification_by_item: dict[Any, dict[str, Any]] = {}
- for row in detail.get("classifications") or []:
- classification_by_item.setdefault(row["item_id"], row)
- decode_by_item: dict[Any, dict[str, Any]] = {}
- for row in detail.get("decode_summaries") or []:
- decode_by_item.setdefault(row["item_id"], row)
- items: list[dict[str, Any]] = []
- platforms: dict[str, dict[str, Any]] = {}
- for raw_job in detail.get("jobs") or []:
- job = _model_dump(raw_job)
- platform = job.get("platform")
- if not platform:
- continue
- platforms.setdefault(
- platform,
- {
- "platform": platform,
- "status": job.get("status") or "pending",
- "attempt_count": job.get("attempt_count"),
- "display_limit": job.get("display_limit"),
- "search_limit": job.get("search_limit"),
- "error_message": job.get("error_message"),
- "items": [],
- },
- )
- for row in detail.get("items") or []:
- item = _model_dump(row)
- item["media_assets"] = [
- MediaAssetSchema.model_validate(media).model_dump(mode="json")
- for media in media_by_item.get(item["id"], [])
- ]
- cls = classification_by_item.get(item["id"])
- item["classification"] = (
- ItemClassificationSchema.model_validate(cls).model_dump(mode="json")
- if cls
- else None
- )
- item["decode_summary"] = _model_dump(decode_by_item[item["id"]]) if item["id"] in decode_by_item else None
- payload = CandidateItemSchema.model_validate(item).model_dump(mode="json")
- items.append(payload)
- group = platforms.setdefault(
- payload["platform"],
- {"platform": payload["platform"], "status": "done", "items": []},
- )
- if group.get("status") in {None, "pending"}:
- group["status"] = "done"
- group["items"].append(payload)
- return {
- "query": QuerySchema.model_validate(detail["query"]).model_dump(mode="json"),
- "jobs": [_model_dump(job) for job in detail.get("jobs") or []],
- "items": items,
- "platforms": platforms,
- }
- @router.get("/query-batches/{batch_id}")
- def query_batch(
- batch_id: UUID,
- repo: AcquisitionRepository = Depends(get_acquisition_repository),
- ) -> dict[str, Any]:
- batch = repo.get_query_batch(batch_id)
- queries = repo.list_queries_for_batch(batch_id)
- return {
- "batch": QueryBatchSchema.model_validate(batch).model_dump(mode="json"),
- "queries": [QuerySchema.model_validate(query).model_dump(mode="json") for query in queries],
- }
- @router.get(
- "/acquisition/runs/{run_id}/summary",
- response_model=AcquisitionRunSummarySchema,
- )
- def acquisition_run_summary(
- run_id: UUID,
- repo: AcquisitionRepository = Depends(get_acquisition_repository),
- ) -> AcquisitionRunSummarySchema:
- return AcquisitionRunSummarySchema.model_validate(repo.get_run_summary(run_id))
- @router.get("/acquisition/runs/{run_id}/queries/{query_id}")
- def acquisition_query_detail(
- run_id: UUID,
- query_id: UUID,
- repo: AcquisitionRepository = Depends(get_acquisition_repository),
- ) -> dict[str, Any]:
- return _normalize_query_detail(repo.get_query_detail(run_id=run_id, query_id=query_id))
|