Spaces:
Running
Running
import streamlit as st | |
import pdfplumber | |
import requests | |
from bs4 import BeautifulSoup | |
from transformers import AutoTokenizer, AutoModel | |
import torch | |
# Load model and tokenizer | |
tokenizer = AutoTokenizer.from_pretrained('sentence-transformers/all-MiniLM-L6-v2') | |
model = AutoModel.from_pretrained('sentence-transformers/all-MiniLM-L6-v2') | |
def extract_text_from_pdf(pdf_file): | |
text = '' | |
with pdfplumber.open(pdf_file) as pdf: | |
for page in pdf.pages: | |
text += page.extract_text() | |
return text | |
def fetch_job_description(url): | |
response = requests.get(url) | |
soup = BeautifulSoup(response.content, 'html.parser') | |
return ' '.join(p.text for p in soup.find_all('p')) | |
def encode(text): | |
encoded_input = tokenizer(text, return_tensors='pt', padding=True, truncation=True, max_length=128) | |
with torch.no_grad(): | |
model_output = model(**encoded_input) | |
return model_output.pooler_output[0] | |
def cosine_similarity(a, b): | |
return (a @ b) / (a.norm() * b.norm()) | |
def calculate_score(resume_text, job_desc_text): | |
resume_emb = encode(resume_text) | |
job_desc_emb = encode(job_desc_text) | |
return cosine_similarity(resume_emb, job_desc_emb).item() | |
st.title('ATS Resume Scorer') | |
with st.sidebar: | |
num_resumes = st.slider("Select number of resumes", 1, 5, 1) | |
uploaded_files = st.file_uploader("Upload resumes", type=['pdf'], accept_multiple_files=True, key="resumes") | |
job_description_input = st.text_area("Paste job description here", height=150) | |
job_url = st.text_input("Or enter job posting URL") | |
if st.button('Score Resumes'): | |
if job_url: | |
job_description = fetch_job_description(job_url) | |
else: | |
job_description = job_description_input | |
if uploaded_files and job_description: | |
scores = [] | |
for uploaded_file in uploaded_files: | |
resume_text = extract_text_from_pdf(uploaded_file) | |
score = calculate_score(resume_text, job_description) | |
scores.append((uploaded_file.name, score)) | |
for name, score in scores: | |
st.write(f"Resume: {name} - Score: {score:.2f}") | |
else: | |
st.error("Please upload at least one resume and provide a job description.") | |