build_creation_demo.py 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. #!/usr/bin/env python3
  2. """Build formal creation-query batches.
  3. Default mode only prints a summary. Use --export-json for a local review file
  4. or --persist to write query_batches/queries into the formal PostgreSQL store.
  5. """
  6. from __future__ import annotations
  7. import argparse
  8. import json
  9. from pathlib import Path
  10. import sys
  11. ROOT = Path(__file__).resolve().parents[1]
  12. if str(ROOT) not in sys.path:
  13. sys.path.insert(0, str(ROOT))
  14. from acquisition.queries.builder import (
  15. QueryBuildOptions,
  16. TREES,
  17. build_creation_query_batch,
  18. persist_query_batch,
  19. )
  20. from acquisition.repositories.postgres import PostgresAcquisitionRepository
  21. from core.config import CreationDbConfig, Settings
  22. from core.db_session import transaction
  23. def parse_args(argv: list[str] | None = None) -> argparse.Namespace:
  24. parser = argparse.ArgumentParser(description=__doc__)
  25. parser.add_argument("--env-file", default=".env")
  26. parser.add_argument("--tree-path", type=Path)
  27. parser.add_argument("--per", type=int, default=0, help="Max queries per family; 0 means all combinations")
  28. parser.add_argument("--batch-n", type=int, default=0, help="Max tree nodes per axis; 0 means all L3/L4 nodes")
  29. parser.add_argument("--seed", type=int, default=7)
  30. parser.add_argument(
  31. "--family",
  32. action="append",
  33. dest="families",
  34. help="Query family key to activate; repeat to enable multiple families",
  35. )
  36. parser.add_argument("--export-json", type=Path, help="Optional local review export")
  37. parser.add_argument("--persist", action="store_true", help="Persist to formal PG")
  38. parser.add_argument("--name", default="creation-demo")
  39. return parser.parse_args(argv)
  40. def _summary(generated: dict) -> dict:
  41. families = generated.get("families") or []
  42. total = sum(len(f.get("items") or []) for f in families)
  43. kept = sum(
  44. 1
  45. for family in families
  46. for item in family.get("items") or []
  47. if item.get("keep", True)
  48. )
  49. return {
  50. "family_count": len(families),
  51. "family_keys": [family.get("key") for family in families],
  52. "query_count": total,
  53. "kept_count": kept,
  54. "metadata": generated.get("metadata") or {},
  55. }
  56. def main(argv: list[str] | None = None) -> int:
  57. args = parse_args(argv)
  58. settings = Settings.from_env(args.env_file)
  59. generated = build_creation_query_batch(
  60. settings,
  61. tree_path=args.tree_path or TREES,
  62. options=QueryBuildOptions(
  63. per=args.per,
  64. batch_n=args.batch_n,
  65. seed=args.seed,
  66. active_family_keys=tuple(args.families) if args.families else ("f1", "f2"),
  67. ),
  68. )
  69. summary = _summary(generated)
  70. if args.export_json:
  71. args.export_json.parent.mkdir(parents=True, exist_ok=True)
  72. args.export_json.write_text(
  73. json.dumps(generated, ensure_ascii=False, indent=1),
  74. encoding="utf-8",
  75. )
  76. summary["export_json"] = str(args.export_json)
  77. if args.persist:
  78. db_config = CreationDbConfig.from_env(args.env_file)
  79. with transaction(db_config) as conn:
  80. repo = PostgresAcquisitionRepository(conn)
  81. batch, count = persist_query_batch(
  82. repo,
  83. generated,
  84. name=args.name,
  85. )
  86. summary["batch_id"] = str(batch.id)
  87. summary["persisted_queries"] = count
  88. print(json.dumps(summary, ensure_ascii=False, indent=2))
  89. return 0
  90. if __name__ == "__main__":
  91. raise SystemExit(main())