File size: 5,347 Bytes
11996bd
08f9d0b
1371e56
 
 
33ff51e
 
11996bd
4dfdb8b
 
 
 
 
 
33ff51e
 
 
 
 
 
 
 
 
 
 
4dfdb8b
 
 
33ff51e
4dfdb8b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
08f9d0b
 
 
4dfdb8b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bdfbee6
4dfdb8b
 
 
 
 
 
 
 
 
 
 
 
 
 
bdfbee6
 
4dfdb8b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
import streamlit as st
import pdfplumber
import io
import spacy
from transformers import pipeline
import subprocess
import sys

st.set_page_config(
    page_title="Resume Screener & Skill Extractor",
    page_icon="πŸ“„",
    layout="wide"
)

# Download spaCy model if not already downloaded
@st.cache_resource
def download_spacy_model():
    try:
        nlp = spacy.load("en_core_web_sm")
    except OSError:
        subprocess.check_call([sys.executable, "-m", "spacy", "download", "en_core_web_sm"])
        nlp = spacy.load("en_core_web_sm")
    return nlp

# Load the NLP models
@st.cache_resource
def load_models():
    summarizer = pipeline("summarization", model="facebook/bart-large-cnn")
    nlp = download_spacy_model()
    return summarizer, nlp

# Initialize models
summarizer, nlp = load_models()

# Job descriptions and required skills
job_descriptions = {
    "Software Engineer": {
        "skills": ["python", "java", "javascript", "sql", "algorithms", "data structures", 
                  "git", "cloud", "web development", "software development", "coding"],
        "description": "Looking for software engineers with strong programming skills and experience in software development."
    },
    "Interaction Designer": {
        "skills": ["ui", "ux", "user research", "wireframing", "prototyping", "figma", 
                  "sketch", "adobe", "design thinking", "interaction design"],
        "description": "Seeking interaction designers with expertise in user experience and interface design."
    },
    "Data Scientist": {
        "skills": ["python", "r", "statistics", "machine learning", "data analysis", 
                  "sql", "tensorflow", "pytorch", "pandas", "numpy"],
        "description": "Looking for data scientists with strong analytical and machine learning skills."
    }
}

def extract_text_from_pdf(pdf_file):
    text = ""
    with pdfplumber.open(pdf_file) as pdf:
        for page in pdf.pages:
            text += page.extract_text() or ""
    return text

def analyze_resume(text, job_title):
    # Extract relevant skills
    doc = nlp(text.lower())
    found_skills = []
    required_skills = job_descriptions[job_title]["skills"]
    
    for skill in required_skills:
        if skill in text.lower():
            found_skills.append(skill)
    
    # Generate summary
    chunks = [text[i:i + 1000] for i in range(0, len(text), 1000)]
    summaries = []
    for chunk in chunks[:3]:  # Process first 3000 characters to avoid token limits
        summary = summarizer(chunk, max_length=150, min_length=50, do_sample=False)[0]["summary_text"]
        summaries.append(summary)
    
    return found_skills, " ".join(summaries)

# Streamlit UI
st.title("πŸ“„ Resume Screener & Skill Extractor")

# Add description
st.markdown("""
This app helps recruiters analyze resumes by:
- Extracting relevant skills for specific job positions
- Generating a concise summary of the candidate's background
- Identifying skill gaps for the selected role
""")

# Create two columns
col1, col2 = st.columns([2, 1])

with col1:
    # File upload
    uploaded_file = st.file_uploader("Upload Resume (PDF)", type=["pdf"])

with col2:
    # Job selection
    job_title = st.selectbox("Select Job Position", list(job_descriptions.keys()))
    
    # Show job description
    if job_title:
        st.info(f"**Required Skills:**\n" + 
                "\n".join([f"- {skill.title()}" for skill in job_descriptions[job_title]["skills"]]))

if uploaded_file and job_title:
    try:
        # Show spinner while processing
        with st.spinner("Analyzing resume..."):
            # Extract text from PDF
            text = extract_text_from_pdf(uploaded_file)
            
            # Analyze resume
            found_skills, summary = analyze_resume(text, job_title)
        
        # Display results in tabs
        tab1, tab2, tab3 = st.tabs(["πŸ“Š Skills Match", "πŸ“ Resume Summary", "🎯 Skills Gap"])
        
        with tab1:
            # Display matched skills
            st.subheader("🎯 Matched Skills")
            if found_skills:
                for skill in found_skills:
                    st.success(f"βœ… {skill.title()}")
                
                # Calculate match percentage
                match_percentage = len(found_skills) / len(job_descriptions[job_title]["skills"]) * 100
                st.metric("Skills Match", f"{match_percentage:.1f}%")
            else:
                st.warning("No direct skill matches found.")
        
        with tab2:
            # Display resume summary
            st.subheader("πŸ“ Resume Summary")
            st.write(summary)
        
        with tab3:
            # Display missing skills
            st.subheader("πŸ“Œ Skills to Develop")
            missing_skills = [skill for skill in job_descriptions[job_title]["skills"] 
                            if skill not in found_skills]
            if missing_skills:
                for skill in missing_skills:
                    st.warning(f"βž– {skill.title()}")
            else:
                st.success("Great! The candidate has all the required skills!")
        
    except Exception as e:
        st.error(f"An error occurred while processing the resume: {str(e)}")

# Add footer
st.markdown("---")
st.markdown("Made with ❀️ using Streamlit and Hugging Face")