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.")