#!/usr/bin/env python3 """Run a JSON file of comments through all filters and print the result. Usage: python filter_comments.py The input file is a JSON list of comments in the shape produced by the API clients' ``get_comments`` (see fetch_comments.py). The filtered list is printed to stdout as JSON; debug logs are written to a log file (see chorus.logging_config). """ import json import os import sys from dotenv import load_dotenv from chorus.filters import apply_filters from chorus.llm.llama_client import OpenAICompatibleLLMClient from chorus.logging_config import configure_logging def build_llm_client() -> OpenAICompatibleLLMClient: """Build the LLM client used by the LLM-based filters. The endpoint/model can be overridden via the environment (see .env.example); otherwise the defaults are used. """ return OpenAICompatibleLLMClient.from_env() def main(argv): if len(argv) != 2: print(f"Usage: {argv[0]} ", file=sys.stderr) return 1 log = configure_logging() load_dotenv() with open(argv[1], encoding="utf-8") as f: data = json.load(f) is_dict = isinstance(data, dict) if is_dict: comments = data.get("comments") or [] metadata = {k: v for k, v in data.items() if k != "comments"} else: comments = data log.info("Loaded %d comment(s) from %s", len(comments), argv[1]) llm_client = build_llm_client() if is_dict: print("{") for k, v in metadata.items(): print(f' "{k}": {json.dumps(v, ensure_ascii=False)},') print(' "comments": [') else: print("[") count = 0 for i, comment in enumerate(apply_filters(comments, llm_client=llm_client)): if i > 0: print(",") json_str = json.dumps(comment, indent=2, ensure_ascii=False) # Indent each line by 2 or 4 spaces to maintain the look of a JSON list indent = " " if is_dict else " " indented = "\n".join(indent + line for line in json_str.splitlines()) print(indented, end="", flush=True) count = i + 1 if is_dict: print("\n ]") print("}") else: print("\n]") log.info("Filtering produced %d comment(s)", count) return 0 if __name__ == "__main__": sys.exit(main(sys.argv))