Spaces:
				
			
			
	
			
			
					
		Running
		
	
	
	
			
			
	
	
	
	
		
		
					
		Running
		
	| import streamlit as st | |
| import pdfplumber | |
| import torch | |
| from transformers import AutoModelForQuestionAnswering, AutoTokenizer, pipeline | |
| # Load Hugging Face model | |
| model_name = "deepset/roberta-base-squad2" | |
| tokenizer = AutoTokenizer.from_pretrained(model_name) | |
| model = AutoModelForQuestionAnswering.from_pretrained(model_name) | |
| qa_pipeline = pipeline( | |
| "question-answering", | |
| model=model, | |
| tokenizer=tokenizer, | |
| truncation=True, | |
| max_length=1024 | |
| ) | |
| # Function to extract text from PDF | |
| def extract_text_from_pdf(pdf_file): | |
| with pdfplumber.open(pdf_file) as pdf: | |
| text = "\n".join([page.extract_text() for page in pdf.pages if page.extract_text()]) | |
| return text if text.strip() else "No text found in the document." | |
| # Function to extract information using LLM | |
| def extract_info(text, question): | |
| if not text or len(text.strip()) < 50: | |
| return "Insufficient text for analysis." | |
| if not question or len(question.strip()) == 0: | |
| return "No valid question provided." | |
| try: | |
| result = qa_pipeline({ | |
| "context": text[:1024], | |
| "question": question | |
| }) | |
| return result.get("answer", "No relevant information found.") | |
| except Exception as e: | |
| return f"Error processing request: {str(e)}" | |
| # Function to analyze resume vs job description | |
| def analyze_resume_vs_job(resume_text, job_desc): | |
| job_keywords = set(job_desc.lower().split()) # Extract keywords from JD | |
| resume_keywords = set(resume_text.lower().split()) # Extract keywords from resume | |
| matched_skills = job_keywords.intersection(resume_keywords) # Common words | |
| missing_skills = job_keywords.difference(resume_keywords) # Missing words | |
| return matched_skills, missing_skills | |
| # Streamlit UI | |
| st.title("π AI-Powered ATS Resume Parser") | |
| st.write("Upload a resume to extract key details automatically!") | |
| uploaded_file = st.file_uploader("Upload Resume (PDF or TXT)", type=["pdf", "txt"]) | |
| if uploaded_file is not None: | |
| file_extension = uploaded_file.name.split(".")[-1] | |
| if file_extension == "pdf": | |
| resume_text = extract_text_from_pdf(uploaded_file) | |
| else: | |
| resume_text = uploaded_file.read().decode("utf-8") | |
| st.subheader("π Extracted Resume Information") | |
| name = extract_info(resume_text, "What is the applicant's name?") | |
| job_title = extract_info(resume_text, "What is the applicant's job title?") | |
| skills = extract_info(resume_text, "What are the applicant's skills?") | |
| experience = extract_info(resume_text, "How many years of experience does the applicant have?") | |
| st.write(f"**π§ Name:** {name}") | |
| st.write(f"**πΌ Job Title:** {job_title}") | |
| st.write(f"**π Skills:** {skills}") | |
| st.write(f"**π Experience:** {experience} years") | |
| # Job Matching (Enhanced) | |
| st.subheader("π Match Resume with Job Description") | |
| job_desc = st.text_area("Paste the Job Description Here:") | |
| if st.button("Match Resume"): | |
| if not job_desc.strip(): | |
| st.warning("β οΈ Please enter a Job Description before matching.") | |
| else: | |
| match_score = extract_info(resume_text, f"How well does this resume match the job description: {job_desc}") | |
| matched_skills, missing_skills = analyze_resume_vs_job(resume_text, job_desc) | |
| st.write(f"**β Match Score:** {match_score}") | |
| st.write(f"**β Matched Skills:** {', '.join(matched_skills) if matched_skills else 'None'}") | |
| st.write(f"**β Missing Skills:** {', '.join(missing_skills) if missing_skills else 'None'}") | |
