""" Redrob Hackathon — Candidate Ranker Sandbox Upload a JSON file of candidates and get back a ranked shortlist. Accepts: JSON array (like sample_candidates.json) or JSONL (one candidate per line). """ import json import tempfile import gradio as gr import pandas as pd from rank import rank_candidates, reasoning def run_ranker(file, top_n): if file is None: return None, "Upload a candidate JSON file to get started." try: top_n = int(top_n) except (ValueError, TypeError): top_n = 10 top_n = max(1, min(top_n, 100)) with tempfile.NamedTemporaryFile(suffix=".json", delete=False, mode="wb") as tmp: tmp.write(file) tmp_path = tmp.name try: ranked = rank_candidates(tmp_path, limit=top_n) except ValueError as e: return None, f"Ranking error: {e}" rows = [] for rank_pos, item in enumerate(ranked, 1): rows.append({ "Rank": rank_pos, "Candidate ID": item["candidate_id"], "Score": round(item["score"], 4), "Reasoning": reasoning(item), }) df = pd.DataFrame(rows) return df, f"Ranked {len(rows)} candidates successfully." with gr.Blocks(title="Redrob Candidate Ranker") as demo: gr.Markdown("## Redrob Hackathon — Candidate Ranker") gr.Markdown( "Upload a JSON file (array format like `sample_candidates.json`, or JSONL) " "and get back a ranked shortlist for the Senior AI Engineer role." ) with gr.Row(): file_input = gr.File(label="Candidate JSON / JSONL", type="binary") top_n_input = gr.Number(label="Top N (max 100)", value=10, precision=0) run_btn = gr.Button("Run Ranker") status = gr.Textbox(label="Status", interactive=False) output_table = gr.Dataframe(label="Ranked Candidates", wrap=True) run_btn.click( fn=run_ranker, inputs=[file_input, top_n_input], outputs=[output_table, status], ) if __name__ == "__main__": demo.launch()