Spaces:
Runtime error
Runtime error
| """ | |
| Bulk Evaluation Script — evaluates all pending complaints in batches of 50. | |
| Queries DB directly for complaint IDs (bypasses API 200-limit), | |
| then evaluates via API with rate limiting between calls. | |
| """ | |
| import os, sys, time, logging | |
| sys.path.insert(0, ".") | |
| from dotenv import load_dotenv; load_dotenv() | |
| import httpx | |
| from db.session import SessionLocal | |
| from db.models import Complaint, Decision | |
| logging.basicConfig(level=logging.INFO, format="%(asctime)s | %(message)s") | |
| logger = logging.getLogger("bulk_eval") | |
| API_BASE = "http://localhost:8000" | |
| BATCH_SIZE = 50 # complaints per batch | |
| SLEEP_CALL = 2.0 # seconds between individual calls (~30/min, within Groq limit) | |
| SLEEP_BATCH = 8.0 # extra pause between batches | |
| def get_pending_ids() -> list[str]: | |
| db = SessionLocal() | |
| try: | |
| decided = {r.complaint_id for r in db.query(Decision.complaint_id).all()} | |
| all_ids = [r.complaint_id for r in db.query(Complaint.complaint_id).all()] | |
| return [cid for cid in all_ids if cid not in decided] | |
| finally: | |
| db.close() | |
| def evaluate_one(cid: str) -> dict: | |
| r = httpx.post(f"{API_BASE}/evaluate/{cid}", timeout=120) | |
| r.raise_for_status() | |
| return r.json() | |
| def main(): | |
| pending = get_pending_ids() | |
| total = len(pending) | |
| logger.info(f"Found {total} pending complaints.") | |
| if total == 0: | |
| logger.info("All complaints already evaluated!"); return | |
| batches = [pending[i:i+BATCH_SIZE] for i in range(0, total, BATCH_SIZE)] | |
| logger.info(f"Running {len(batches)} batches of {BATCH_SIZE}.") | |
| success, failed, done = 0, 0, 0 | |
| for b_num, batch in enumerate(batches, 1): | |
| logger.info(f"\n── Batch {b_num}/{len(batches)} ({len(batch)} complaints) ──") | |
| for cid in batch: | |
| done += 1 | |
| try: | |
| d = evaluate_one(cid) | |
| logger.info(f" [{done}/{total}] {cid} → {d.get('ai_decision')} (conf:{d.get('ai_confidence',0):.2f})") | |
| success += 1 | |
| except Exception as e: | |
| logger.error(f" [{done}/{total}] {cid} FAILED: {e}") | |
| failed += 1 | |
| time.sleep(SLEEP_CALL) | |
| if b_num < len(batches): | |
| logger.info(f" Batch {b_num} done. Pausing {SLEEP_BATCH}s...") | |
| time.sleep(SLEEP_BATCH) | |
| logger.info(f"\n{'='*50}") | |
| logger.info(f"✅ Done: {success} success, {failed} failed / {total} total.") | |
| if __name__ == "__main__": | |
| main() | |