Spaces:
Sleeping
Sleeping
Download app.py from billyxx/Sprouts_Assignment: direct link, hf CLI and curl.
- Browser
- Download file 3.11 kB
-
https://huggingface.co/spaces/billyxx/Sprouts_Assignment/resolve/main/app.py
- Command line
-
hf download hf://spaces/billyxx/Sprouts_Assignment/app.py
-
curl -L -o app.py https://huggingface.co/spaces/billyxx/Sprouts_Assignment/resolve/main/app.py
3.11 kB
| import gradio as gr | |
| import os | |
| import shutil | |
| from recommender import rank_resumes, summarize_resume_flan, extract_applicant_name | |
| from docx import Document | |
| import pdfplumber | |
| UPLOAD_FOLDER = "uploads" | |
| os.makedirs(UPLOAD_FOLDER, exist_ok=True) | |
| def process_resumes(job_description, uploaded_files): | |
| if not job_description.strip(): | |
| return "Please provide a job description.", None | |
| resume_texts = [] | |
| for uploaded_file in uploaded_files: | |
| filename = os.path.basename(uploaded_file.name) | |
| ext = filename.lower().split(".")[-1] | |
| # Copying the file from Gradio temp folder to uploads folder | |
| file_path = os.path.join(UPLOAD_FOLDER, filename) | |
| shutil.copy(uploaded_file.name, file_path) | |
| if ext == "txt": | |
| with open(file_path, "r", encoding="utf-8") as f: | |
| text = f.read() | |
| elif ext == "pdf": | |
| try: | |
| with pdfplumber.open(file_path) as pdf: | |
| pages = [page.extract_text() for page in pdf.pages if page.extract_text() is not None] | |
| if not pages: | |
| return f"No extractable text found in PDF: {filename}. Is it scanned or image-only?", None | |
| text = "\n".join(pages) | |
| except Exception as e: | |
| return f"Failed to process PDF {filename}: {str(e)}", None | |
| elif ext == "docx": | |
| try: | |
| doc = Document(file_path) | |
| text = "\n".join([p.text for p in doc.paragraphs]) | |
| except Exception as e: | |
| return f"Failed to process DOCX {filename}: {str(e)}", None | |
| else: | |
| return f"Unsupported file format: {filename}", None | |
| resume_texts.append((filename, text)) | |
| # Rank resumes and generate summaries | |
| results = rank_resumes(job_description, resume_texts) | |
| # Attach filename to each candidate for display | |
| for i, candidate in enumerate(results): | |
| candidate["filename"] = resume_texts[i][0] | |
| for candidate in results: | |
| candidate["summary"] = summarize_resume_flan(candidate["text"], job_description) | |
| table_data = [ | |
| [ | |
| candidate.get("applicant_name", extract_applicant_name(candidate["text"], candidate.get("filename", "Unknown"))), | |
| candidate.get("filename", "Unknown"), | |
| f"{candidate['score']:.4f}", | |
| candidate["summary"] | |
| ] for candidate in results | |
| ] | |
| return "", table_data | |
| with gr.Blocks() as demo: | |
| gr.Markdown("## Candidate Recommendation Engine") | |
| with gr.Row(): | |
| job_desc = gr.Textbox(label="Job Description", lines=10, placeholder="Paste job description here...") | |
| resumes = gr.Files(label="Upload Resumes (.txt, .pdf, .docx)", file_types=[".txt", ".pdf", ".docx"]) | |
| btn = gr.Button("Rank Candidates") | |
| msg = gr.Markdown() | |
| output_table = gr.Dataframe(headers=["Candidate", "File Name", "Similarity Score", "Why a Good Fit"], wrap=True) | |
| btn.click(process_resumes, inputs=[job_desc, resumes], outputs=[msg, output_table]) | |
| if __name__ == "__main__": | |
| demo.launch() | |