Last commit not found
import streamlit as st | |
import pdfplumber | |
import io | |
import spacy | |
from transformers import pipeline | |
st.set_page_config( | |
page_title="Resume Screener & Skill Extractor", | |
page_icon="π", | |
layout="wide" | |
) | |
# Load the NLP model | |
def load_models(): | |
summarizer = pipeline("summarization", model="facebook/bart-large-cnn") | |
nlp = spacy.load("en_core_web_sm") | |
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") | |