import gradio as gr import pandas as pd import traceback from model import screen_resumes_backend def process(job_description, files, model_option, threshold, gmail, password): try: if not job_description or len(job_description) < 20: return "❌ Job description too short", None, None # if email provided → use Gmail mode if gmail and password: results, report, zip_path = screen_resumes_backend( job_description, files=None, model_name=model_option, threshold=threshold, gmail=gmail, password=password ) else: # file upload mode if not files: return "❌ Upload files or provide email", None, None results, report, zip_path = screen_resumes_backend( job_description, files, model_option, threshold ) df = pd.DataFrame(results) return "✅ Process Completed", df, zip_path except Exception as e: return f"❌ Error: {str(e)}\n{traceback.format_exc()}", None, None # ================= UI ================= with gr.Blocks(title="AI Resume Screener") as demo: gr.Markdown("# 🧠 AI Resume Screening System") job_desc = gr.Textbox(label="Job Description", lines=6) model = gr.Dropdown( ["Fast (MiniLM)", "Balanced (Recommended)", "High Accuracy"], value="Balanced (Recommended)" ) threshold = gr.Slider(0.4, 0.9, value=0.6) # 🔥 NEW: EMAIL SECTION gr.Markdown("## 📧 Email Integration (Optional)") gmail = gr.Textbox(label="Gmail Address") password = gr.Textbox(label="App Password (NOT normal password)", type="password") gr.Markdown("OR Upload Files Below 👇") files = gr.File(file_count="multiple", label="Upload CVs (PDF/DOCX)") btn = gr.Button("Process") output_text = gr.Markdown() output_table = gr.DataFrame() download_zip = gr.File() btn.click( process, inputs=[job_desc, files, model, threshold, gmail, password], outputs=[output_text, output_table, download_zip] ) demo.launch()