root
sss
33ff51e
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")