Spaces:
Build error
Build error
Update app.py
Browse files
app.py
CHANGED
@@ -6,6 +6,10 @@ import streamlit as st
|
|
6 |
from smolagents import CodeAgent, HfApiModel, DuckDuckGoSearchTool
|
7 |
from io import BytesIO
|
8 |
|
|
|
|
|
|
|
|
|
9 |
# Configure page
|
10 |
st.set_page_config(
|
11 |
page_title="Resume Scorer",
|
@@ -13,16 +17,13 @@ st.set_page_config(
|
|
13 |
layout="wide"
|
14 |
)
|
15 |
|
16 |
-
# Initialize the model and agent
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
except Exception as e:
|
24 |
-
st.error(f"Error initializing agent: {e}")
|
25 |
-
return None
|
26 |
|
27 |
def extract_text_from_uploaded_pdf(pdf_file):
|
28 |
"""Extracts text from an uploaded PDF file."""
|
@@ -37,8 +38,12 @@ def extract_text_from_uploaded_pdf(pdf_file):
|
|
37 |
st.error(f"Error extracting text from PDF: {e}")
|
38 |
return None
|
39 |
|
40 |
-
def score_resume_against_job_description(
|
41 |
"""Scores a resume against a job description using smolagents."""
|
|
|
|
|
|
|
|
|
42 |
prompt = f"""
|
43 |
You are a professional recruiter that is highly skilled in scoring resumes.
|
44 |
You will receive a resume and a job description.
|
@@ -55,7 +60,7 @@ def score_resume_against_job_description(agent, resume_text, job_description):
|
|
55 |
try:
|
56 |
response = agent.run(prompt)
|
57 |
# Ensure we get a numeric response
|
58 |
-
score = int(''.join(filter(str.isdigit, response)))
|
59 |
return min(max(score, 0), 100) # Ensure score is between 0 and 100
|
60 |
except Exception as e:
|
61 |
st.error(f"An error has occurred: {e}")
|
@@ -66,109 +71,81 @@ def extract_links_from_text(text):
|
|
66 |
links = re.findall(r'(https?://\S+)', text)
|
67 |
return links
|
68 |
|
69 |
-
|
70 |
-
st.
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
with col1:
|
97 |
-
st.subheader("Upload Resume")
|
98 |
-
uploaded_file = st.file_uploader("Upload Resume (PDF)", type="pdf")
|
99 |
-
|
100 |
-
with col2:
|
101 |
-
st.subheader("Job Description")
|
102 |
-
job_description = st.text_area(
|
103 |
-
"Enter Job Description",
|
104 |
-
height=200,
|
105 |
-
placeholder="Paste the job description here..."
|
106 |
-
)
|
107 |
-
|
108 |
-
if uploaded_file and job_description:
|
109 |
-
if st.button("Score Resume"):
|
110 |
-
with st.spinner("Analyzing resume..."):
|
111 |
-
# Extract text from uploaded PDF
|
112 |
-
resume_text = extract_text_from_uploaded_pdf(uploaded_file)
|
113 |
-
|
114 |
-
if resume_text:
|
115 |
-
# Extract links
|
116 |
-
links = extract_links_from_text(resume_text)
|
117 |
-
|
118 |
-
# Get score
|
119 |
-
score = score_resume_against_job_description(agent, resume_text, job_description)
|
120 |
-
|
121 |
-
# Display results
|
122 |
-
st.divider()
|
123 |
-
st.subheader("Results")
|
124 |
|
125 |
-
if
|
126 |
-
|
127 |
-
|
128 |
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
# Add color-coded feedback
|
133 |
-
if score >= 80:
|
134 |
-
st.success("Strong match! π")
|
135 |
-
elif score >= 60:
|
136 |
-
st.info("Good match! π")
|
137 |
-
else:
|
138 |
-
st.warning("Consider revising the resume to better match the job requirements")
|
139 |
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
147 |
else:
|
148 |
-
st.error("
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
This tool uses AI to analyze resumes and provide
|
169 |
-
matching scores against job descriptions. The score
|
170 |
-
is based on:
|
171 |
-
- Skills match
|
172 |
-
- Experience relevance
|
173 |
-
- Qualification alignment
|
174 |
-
""")
|
|
|
6 |
from smolagents import CodeAgent, HfApiModel, DuckDuckGoSearchTool
|
7 |
from io import BytesIO
|
8 |
|
9 |
+
# Disable SSL verification warning
|
10 |
+
import urllib3
|
11 |
+
urllib3.disable_warnings()
|
12 |
+
|
13 |
# Configure page
|
14 |
st.set_page_config(
|
15 |
page_title="Resume Scorer",
|
|
|
17 |
layout="wide"
|
18 |
)
|
19 |
|
20 |
+
# Initialize the model and agent - moved outside of cache
|
21 |
+
try:
|
22 |
+
model = HfApiModel()
|
23 |
+
agent = CodeAgent(tools=[DuckDuckGoSearchTool()], model=model)
|
24 |
+
except Exception as e:
|
25 |
+
st.error(f"Error initializing agent: {e}")
|
26 |
+
agent = None
|
|
|
|
|
|
|
27 |
|
28 |
def extract_text_from_uploaded_pdf(pdf_file):
|
29 |
"""Extracts text from an uploaded PDF file."""
|
|
|
38 |
st.error(f"Error extracting text from PDF: {e}")
|
39 |
return None
|
40 |
|
41 |
+
def score_resume_against_job_description(resume_text, job_description):
|
42 |
"""Scores a resume against a job description using smolagents."""
|
43 |
+
if agent is None:
|
44 |
+
st.error("Agent not initialized properly")
|
45 |
+
return None
|
46 |
+
|
47 |
prompt = f"""
|
48 |
You are a professional recruiter that is highly skilled in scoring resumes.
|
49 |
You will receive a resume and a job description.
|
|
|
60 |
try:
|
61 |
response = agent.run(prompt)
|
62 |
# Ensure we get a numeric response
|
63 |
+
score = int(''.join(filter(str.isdigit, str(response))))
|
64 |
return min(max(score, 0), 100) # Ensure score is between 0 and 100
|
65 |
except Exception as e:
|
66 |
st.error(f"An error has occurred: {e}")
|
|
|
71 |
links = re.findall(r'(https?://\S+)', text)
|
72 |
return links
|
73 |
|
74 |
+
def main():
|
75 |
+
st.title("π Resume Scorer")
|
76 |
+
st.write("Upload a resume and enter a job description to get a matching score!")
|
77 |
+
|
78 |
+
if agent is None:
|
79 |
+
st.error("Failed to initialize the scoring system. Please try again later.")
|
80 |
+
return
|
81 |
+
|
82 |
+
# Create two columns
|
83 |
+
col1, col2 = st.columns(2)
|
84 |
+
|
85 |
+
with col1:
|
86 |
+
st.subheader("Upload Resume")
|
87 |
+
uploaded_file = st.file_uploader("Upload Resume (PDF)", type="pdf")
|
88 |
+
|
89 |
+
with col2:
|
90 |
+
st.subheader("Job Description")
|
91 |
+
job_description = st.text_area(
|
92 |
+
"Enter Job Description",
|
93 |
+
height=200,
|
94 |
+
placeholder="Paste the job description here..."
|
95 |
+
)
|
96 |
+
|
97 |
+
if uploaded_file and job_description:
|
98 |
+
if st.button("Score Resume"):
|
99 |
+
with st.spinner("Analyzing resume..."):
|
100 |
+
resume_text = extract_text_from_uploaded_pdf(uploaded_file)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
101 |
|
102 |
+
if resume_text:
|
103 |
+
links = extract_links_from_text(resume_text)
|
104 |
+
score = score_resume_against_job_description(resume_text, job_description)
|
105 |
|
106 |
+
st.divider()
|
107 |
+
st.subheader("Results")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
108 |
|
109 |
+
if score is not None:
|
110 |
+
score_col, links_col = st.columns(2)
|
111 |
+
|
112 |
+
with score_col:
|
113 |
+
st.metric("Resume Match Score", f"{score}/100")
|
114 |
+
|
115 |
+
if score >= 80:
|
116 |
+
st.success("Strong match! π")
|
117 |
+
elif score >= 60:
|
118 |
+
st.info("Good match! π")
|
119 |
+
else:
|
120 |
+
st.warning("Consider revising the resume")
|
121 |
+
|
122 |
+
with links_col:
|
123 |
+
if links:
|
124 |
+
st.subheader("Links found in Resume:")
|
125 |
+
for link in links:
|
126 |
+
st.write(f"- {link}")
|
127 |
+
else:
|
128 |
+
st.info("No links found in the resume")
|
129 |
+
else:
|
130 |
+
st.error("Error calculating score")
|
131 |
else:
|
132 |
+
st.error("Could not extract text from the PDF")
|
133 |
+
|
134 |
+
with st.sidebar:
|
135 |
+
st.header("How to Use")
|
136 |
+
st.write("""
|
137 |
+
1. Upload a PDF resume
|
138 |
+
2. Paste the job description
|
139 |
+
3. Click 'Score Resume'
|
140 |
+
""")
|
141 |
+
|
142 |
+
st.divider()
|
143 |
+
|
144 |
+
st.markdown("""
|
145 |
+
### About
|
146 |
+
This tool uses AI to analyze resumes and provide
|
147 |
+
matching scores against job descriptions.
|
148 |
+
""")
|
149 |
+
|
150 |
+
if __name__ == "__main__":
|
151 |
+
main()
|
|
|
|
|
|
|
|
|
|
|
|
|
|