query_generation.py 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. """Formal query-generation preview API routes."""
  2. from __future__ import annotations
  3. from typing import Any
  4. from uuid import UUID
  5. from fastapi import APIRouter, Depends, Query
  6. from acquisition.queries.builder import QueryBuildOptions, TREES, build_creation_query_batch
  7. from app.dependencies import _env_file, get_acquisition_repository
  8. from app.routes.acquisition import _normalize_query_detail
  9. from core.config import Settings
  10. router = APIRouter(prefix="/api/query-generation", tags=["query-generation"])
  11. def _summary(generated: dict[str, Any]) -> dict[str, Any]:
  12. families = generated.get("families") or []
  13. return {
  14. "family_count": len(families),
  15. "family_keys": [family.get("key") for family in families],
  16. "query_count": sum(len(family.get("items") or []) for family in families),
  17. "kept_count": sum(
  18. 1
  19. for family in families
  20. for item in family.get("items") or []
  21. if item.get("keep", True)
  22. ),
  23. }
  24. @router.get("/preview")
  25. def query_generation_preview(
  26. per: int = Query(default=0, ge=0, le=10000),
  27. batch_n: int = Query(default=0, ge=0, le=1000),
  28. dry: bool = Query(default=True),
  29. ) -> dict[str, Any]:
  30. """Preview the currently active formal query families without writing DB rows."""
  31. settings = Settings.from_env(_env_file())
  32. generated = build_creation_query_batch(
  33. settings,
  34. tree_path=TREES,
  35. options=QueryBuildOptions(
  36. per=per,
  37. batch_n=batch_n,
  38. dry=dry,
  39. active_family_keys=("f1", "f2"),
  40. ),
  41. )
  42. generated["summary"] = _summary(generated)
  43. return generated
  44. @router.get("/latest-singleton")
  45. def latest_singleton_overview(repo: Any = Depends(get_acquisition_repository)) -> dict[str, Any]:
  46. """Return links from the query preview board to the latest real singleton run."""
  47. getter = getattr(repo, "get_latest_singleton_overview", None)
  48. if getter is None:
  49. return {"batch": None, "run": None, "queries": [], "decoded_items": []}
  50. return getter()
  51. @router.get("/latest/queries/{query_id}")
  52. def latest_query_detail(
  53. query_id: UUID,
  54. repo: Any = Depends(get_acquisition_repository),
  55. ) -> dict[str, Any]:
  56. """Return search material for one query in the latest real query board batch."""
  57. overview_getter = getattr(repo, "get_latest_singleton_overview", None)
  58. detail_getter = getattr(repo, "get_query_detail_for_batch", None)
  59. if overview_getter is None or detail_getter is None:
  60. return {"query": None, "jobs": [], "items": [], "platforms": {}}
  61. overview = overview_getter()
  62. batch = overview.get("batch")
  63. batch_id = batch.get("id") if isinstance(batch, dict) else getattr(batch, "id", None)
  64. if batch_id is None:
  65. return {"query": None, "jobs": [], "items": [], "platforms": {}}
  66. return _normalize_query_detail(detail_getter(batch_id=batch_id, query_id=query_id))