Spaces:
				
			
			
	
			
			
					
		Running
		
	
	
	
			
			
	
	
	
	
		
		
					
		Running
		
	Upload 2 files
Browse files- app.py +87 -0
- reruirements.txt +4 -0
    	
        app.py
    ADDED
    
    | @@ -0,0 +1,87 @@ | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | 
|  | |
| 1 | 
            +
            import streamlit as st
         | 
| 2 | 
            +
            import pdfplumber
         | 
| 3 | 
            +
            import torch
         | 
| 4 | 
            +
            from transformers import AutoModelForQuestionAnswering, AutoTokenizer, pipeline
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            # Load Hugging Face model
         | 
| 7 | 
            +
            model_name = "deepset/roberta-base-squad2"
         | 
| 8 | 
            +
            tokenizer = AutoTokenizer.from_pretrained(model_name)
         | 
| 9 | 
            +
            model = AutoModelForQuestionAnswering.from_pretrained(model_name)
         | 
| 10 | 
            +
            qa_pipeline = pipeline(
         | 
| 11 | 
            +
                "question-answering",
         | 
| 12 | 
            +
                model=model,
         | 
| 13 | 
            +
                tokenizer=tokenizer,
         | 
| 14 | 
            +
                truncation=True,
         | 
| 15 | 
            +
                max_length=1024
         | 
| 16 | 
            +
            )
         | 
| 17 | 
            +
             | 
| 18 | 
            +
            # Function to extract text from PDF
         | 
| 19 | 
            +
            def extract_text_from_pdf(pdf_file):
         | 
| 20 | 
            +
                with pdfplumber.open(pdf_file) as pdf:
         | 
| 21 | 
            +
                    text = "\n".join([page.extract_text() for page in pdf.pages if page.extract_text()])
         | 
| 22 | 
            +
                    return text if text.strip() else "No text found in the document."
         | 
| 23 | 
            +
             | 
| 24 | 
            +
            # Function to extract information using LLM
         | 
| 25 | 
            +
            def extract_info(text, question):
         | 
| 26 | 
            +
                if not text or len(text.strip()) < 50:
         | 
| 27 | 
            +
                    return "Insufficient text for analysis."
         | 
| 28 | 
            +
                if not question or len(question.strip()) == 0:
         | 
| 29 | 
            +
                    return "No valid question provided."
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                try:
         | 
| 32 | 
            +
                    result = qa_pipeline({
         | 
| 33 | 
            +
                        "context": text[:1024],
         | 
| 34 | 
            +
                        "question": question
         | 
| 35 | 
            +
                    })
         | 
| 36 | 
            +
                    return result.get("answer", "No relevant information found.")
         | 
| 37 | 
            +
                except Exception as e:
         | 
| 38 | 
            +
                    return f"Error processing request: {str(e)}"
         | 
| 39 | 
            +
             | 
| 40 | 
            +
            # Function to analyze resume vs job description
         | 
| 41 | 
            +
            def analyze_resume_vs_job(resume_text, job_desc):
         | 
| 42 | 
            +
                job_keywords = set(job_desc.lower().split())  # Extract keywords from JD
         | 
| 43 | 
            +
                resume_keywords = set(resume_text.lower().split())  # Extract keywords from resume
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                matched_skills = job_keywords.intersection(resume_keywords)  # Common words
         | 
| 46 | 
            +
                missing_skills = job_keywords.difference(resume_keywords)  # Missing words
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                return matched_skills, missing_skills
         | 
| 49 | 
            +
             | 
| 50 | 
            +
            # Streamlit UI
         | 
| 51 | 
            +
            st.title("π AI-Powered ATS Resume Parser")
         | 
| 52 | 
            +
            st.write("Upload a resume to extract key details automatically!")
         | 
| 53 | 
            +
             | 
| 54 | 
            +
            uploaded_file = st.file_uploader("Upload Resume (PDF or TXT)", type=["pdf", "txt"])
         | 
| 55 | 
            +
             | 
| 56 | 
            +
            if uploaded_file is not None:
         | 
| 57 | 
            +
                file_extension = uploaded_file.name.split(".")[-1]
         | 
| 58 | 
            +
                if file_extension == "pdf":
         | 
| 59 | 
            +
                    resume_text = extract_text_from_pdf(uploaded_file)
         | 
| 60 | 
            +
                else:
         | 
| 61 | 
            +
                    resume_text = uploaded_file.read().decode("utf-8")
         | 
| 62 | 
            +
             | 
| 63 | 
            +
                st.subheader("π Extracted Resume Information")
         | 
| 64 | 
            +
                name = extract_info(resume_text, "What is the applicant's name?")
         | 
| 65 | 
            +
                job_title = extract_info(resume_text, "What is the applicant's job title?")
         | 
| 66 | 
            +
                skills = extract_info(resume_text, "What are the applicant's skills?")
         | 
| 67 | 
            +
                experience = extract_info(resume_text, "How many years of experience does the applicant have?")
         | 
| 68 | 
            +
             | 
| 69 | 
            +
                st.write(f"**π§ Name:** {name}")
         | 
| 70 | 
            +
                st.write(f"**πΌ Job Title:** {job_title}")
         | 
| 71 | 
            +
                st.write(f"**π  Skills:** {skills}")
         | 
| 72 | 
            +
                st.write(f"**π
 Experience:** {experience} years")
         | 
| 73 | 
            +
             | 
| 74 | 
            +
                # Job Matching (Enhanced)
         | 
| 75 | 
            +
                st.subheader("π Match Resume with Job Description")
         | 
| 76 | 
            +
                job_desc = st.text_area("Paste the Job Description Here:")
         | 
| 77 | 
            +
             | 
| 78 | 
            +
                if st.button("Match Resume"):
         | 
| 79 | 
            +
                    if not job_desc.strip():
         | 
| 80 | 
            +
                        st.warning("β οΈ Please enter a Job Description before matching.")
         | 
| 81 | 
            +
                    else:
         | 
| 82 | 
            +
                        match_score = extract_info(resume_text, f"How well does this resume match the job description: {job_desc}")
         | 
| 83 | 
            +
                        matched_skills, missing_skills = analyze_resume_vs_job(resume_text, job_desc)
         | 
| 84 | 
            +
             | 
| 85 | 
            +
                        st.write(f"**β
 Match Score:** {match_score}")
         | 
| 86 | 
            +
                        st.write(f"**β Matched Skills:** {', '.join(matched_skills) if matched_skills else 'None'}")
         | 
| 87 | 
            +
                        st.write(f"**β Missing Skills:** {', '.join(missing_skills) if missing_skills else 'None'}")
         | 
    	
        reruirements.txt
    ADDED
    
    | @@ -0,0 +1,4 @@ | |
|  | |
|  | |
|  | |
|  | 
|  | |
| 1 | 
            +
            streamlit
         | 
| 2 | 
            +
            transformers
         | 
| 3 | 
            +
            torch
         | 
| 4 | 
            +
            pdfplumber
         | 
