Spaces:
Running
Running
app.py
Browse files
app.py
ADDED
@@ -0,0 +1,64 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
import pdfplumber
|
3 |
+
import requests
|
4 |
+
from bs4 import BeautifulSoup
|
5 |
+
from transformers import AutoTokenizer, AutoModel
|
6 |
+
import torch
|
7 |
+
|
8 |
+
# Load model and tokenizer
|
9 |
+
tokenizer = AutoTokenizer.from_pretrained('sentence-transformers/all-MiniLM-L6-v2')
|
10 |
+
model = AutoModel.from_pretrained('sentence-transformers/all-MiniLM-L6-v2')
|
11 |
+
|
12 |
+
def extract_text_from_pdf(pdf_file):
|
13 |
+
text = ''
|
14 |
+
with pdfplumber.open(pdf_file) as pdf:
|
15 |
+
for page in pdf.pages:
|
16 |
+
text += page.extract_text()
|
17 |
+
return text
|
18 |
+
|
19 |
+
def fetch_job_description(url):
|
20 |
+
response = requests.get(url)
|
21 |
+
soup = BeautifulSoup(response.content, 'html.parser')
|
22 |
+
return ' '.join(p.text for p in soup.find_all('p'))
|
23 |
+
|
24 |
+
def encode(text):
|
25 |
+
encoded_input = tokenizer(text, return_tensors='pt', padding=True, truncation=True, max_length=128)
|
26 |
+
with torch.no_grad():
|
27 |
+
model_output = model(**encoded_input)
|
28 |
+
return model_output.pooler_output[0]
|
29 |
+
|
30 |
+
def cosine_similarity(a, b):
|
31 |
+
return (a @ b) / (a.norm() * b.norm())
|
32 |
+
|
33 |
+
def calculate_score(resume_text, job_desc_text):
|
34 |
+
resume_emb = encode(resume_text)
|
35 |
+
job_desc_emb = encode(job_desc_text)
|
36 |
+
return cosine_similarity(resume_emb, job_desc_emb).item()
|
37 |
+
|
38 |
+
st.title('ATS Resume Scorer')
|
39 |
+
|
40 |
+
with st.sidebar:
|
41 |
+
num_resumes = st.slider("Select number of resumes", 1, 5, 1)
|
42 |
+
|
43 |
+
uploaded_files = st.file_uploader("Upload resumes", type=['pdf'], accept_multiple_files=True, key="resumes")
|
44 |
+
|
45 |
+
job_description_input = st.text_area("Paste job description here", height=150)
|
46 |
+
job_url = st.text_input("Or enter job posting URL")
|
47 |
+
|
48 |
+
if st.button('Score Resumes'):
|
49 |
+
if job_url:
|
50 |
+
job_description = fetch_job_description(job_url)
|
51 |
+
else:
|
52 |
+
job_description = job_description_input
|
53 |
+
|
54 |
+
if uploaded_files and job_description:
|
55 |
+
scores = []
|
56 |
+
for uploaded_file in uploaded_files:
|
57 |
+
resume_text = extract_text_from_pdf(uploaded_file)
|
58 |
+
score = calculate_score(resume_text, job_description)
|
59 |
+
scores.append((uploaded_file.name, score))
|
60 |
+
|
61 |
+
for name, score in scores:
|
62 |
+
st.write(f"Resume: {name} - Score: {score:.2f}")
|
63 |
+
else:
|
64 |
+
st.error("Please upload at least one resume and provide a job description.")
|