JAA-ATS-Tool / src /run_history.py
saitejatirunagari's picture
feat: UI redesign, 2 new platforms, per-platform cap, run history, all-jobs resumes
df898a6
Raw
History Blame
3.22 kB
"""
Run history — saves and loads completed pipeline runs as JSON.
Each run is stored at data/output/run_history/run_YYYY-MM-DD_HH-MM-SS.json.
Keeps the full job list so results can be restored in the UI without rerunning.
"""
import json
import logging
from pathlib import Path
from datetime import datetime
log = logging.getLogger("run_history")
HISTORY_DIR = Path("data/output/run_history")
def save_run(jobs: list, run_meta: dict) -> str:
"""
Save a completed run to history.
run_meta should include: run_id, excel_path, platforms, roles.
Returns the history file path, or '' on failure.
"""
HISTORY_DIR.mkdir(parents=True, exist_ok=True)
run_id = run_meta.get("run_id") or datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
high = sum(1 for j in jobs if j.get("relevance_score", 0) >= 8)
med = sum(1 for j in jobs if 6 <= j.get("relevance_score", 0) <= 7)
resumes = sum(1 for j in jobs if j.get("resume_path"))
pdfs = sum(1 for j in jobs if j.get("resume_pdf_path"))
ats_before = [j["ats_score_before"] for j in jobs
if j.get("ats_score_before") not in (None, "", 0)]
ats_after = [j["ats_score_after"] for j in jobs
if j.get("ats_score_after") not in (None, "", 0)]
record = {
"run_id": run_id,
"date": datetime.now().strftime("%Y-%m-%d %H:%M"),
"total_jobs": len(jobs),
"high_priority": high,
"med_priority": med,
"resumes": resumes,
"pdfs": pdfs,
"avg_ats_before": int(sum(ats_before) / len(ats_before)) if ats_before else 0,
"avg_ats_after": int(sum(ats_after) / len(ats_after)) if ats_after else 0,
"platforms": list(set(j.get("platform", "") for j in jobs if j.get("platform"))),
"roles": run_meta.get("roles", []),
"excel_path": run_meta.get("excel_path", ""),
"jobs": jobs,
}
path = HISTORY_DIR / f"run_{run_id}.json"
try:
with open(path, "w", encoding="utf-8") as f:
json.dump(record, f, ensure_ascii=False, default=str)
log.info(f"Run saved to history: {path}")
return str(path)
except Exception as e:
log.error(f"Failed to save run history: {e}")
return ""
def list_runs() -> list:
"""
List all saved runs, newest first.
Returns list of summary dicts (no jobs key — kept light for UI listing).
"""
if not HISTORY_DIR.exists():
return []
runs = []
for p in sorted(HISTORY_DIR.glob("run_*.json"), reverse=True):
try:
with open(p, "r", encoding="utf-8") as f:
data = json.load(f)
summary = {k: v for k, v in data.items() if k != "jobs"}
summary["_path"] = str(p)
runs.append(summary)
except Exception:
pass
return runs
def load_run(path: str) -> dict:
"""Load a full run (including jobs list) from a history JSON file."""
try:
with open(path, "r", encoding="utf-8") as f:
return json.load(f)
except Exception as e:
log.error(f"Failed to load run {path}: {e}")
return {}