run_decode_content.py 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041
  1. """Run the formal single-item decode workflow.
  2. This CLI is intentionally thin. Production loading should come from the formal
  3. candidate item repository; fixture loading is kept only for local smoke checks.
  4. """
  5. from __future__ import annotations
  6. import argparse
  7. import json
  8. from pathlib import Path
  9. from uuid import UUID, uuid4
  10. from acquisition.crawler import parse_detail_response
  11. from core.config import Settings
  12. from decode_content.service import DecodeService
  13. ROOT = Path(__file__).resolve().parent.parent
  14. def _load_fixture(path: Path):
  15. payload = json.loads(path.read_text(encoding="utf-8"))
  16. return parse_detail_response(payload, fallback_content_id=path.stem.removeprefix("xhs_case_"))
  17. def main() -> None:
  18. parser = argparse.ArgumentParser(description="Decode one creation candidate through decode_content.")
  19. parser.add_argument("--fixture", type=Path, help="local fixture JSON for smoke runs")
  20. parser.add_argument("--item-id", help="candidate item UUID; generated when omitted for fixture smoke")
  21. args = parser.parse_args()
  22. if not args.fixture:
  23. parser.error("formal DB item loading is wired in pipeline Step 6; pass --fixture for local smoke")
  24. item_id = UUID(args.item_id) if args.item_id else uuid4()
  25. post = _load_fixture(args.fixture if args.fixture.is_absolute() else ROOT / args.fixture)
  26. service = DecodeService(settings=Settings.from_env())
  27. output = service.decode_post(item_id=item_id, post=post)
  28. print(json.dumps({"item_id": str(item_id), "status": output.status, "payload_count": len(output.payloads)}, ensure_ascii=False))
  29. if __name__ == "__main__":
  30. main()