Spaces:
Running
Running
import streamlit as st | |
import google.generativeai as genai | |
import os | |
import PyPDF2 as pdf | |
from dotenv import load_dotenv | |
import json | |
import re | |
import time | |
load_dotenv() | |
genai.configure(api_key=os.getenv('GOOGLE_API_KEY')) | |
def get_gemeni_response(input_text): | |
model = genai.GenerativeModel('gemini-pro') | |
response = model.generate_content(input_text) | |
return response.text | |
def input_pdf_text(upload_file): | |
reader = pdf.PdfReader(upload_file) | |
text = "" | |
for page in range(len(reader.pages)): | |
page_text = reader.pages[page].extract_text() | |
text += str(page_text) | |
return text | |
def parse_response(response): | |
"""Validate and parse JSON response string.""" | |
# Ensure response is JSON-like with regex before parsing | |
if re.match(r'^\{.*\}$', response.strip(), re.DOTALL): | |
try: | |
return json.loads(response) | |
except json.JSONDecodeError: | |
return None | |
return None | |
# Enhanced Prompt Engineering | |
input_prompt = """ | |
Act as a highly skilled ATS (Applicant Tracking System) expert with strong knowledge of software engineering, data science, analytics, and big data engineering. | |
Your goal is to analyze the resume content and compare it to the provided job description. Provide the following: | |
1. An overall Job Description (JD) Match percentage. | |
2. Top missing keywords or phrases relevant to the job description. | |
3. A summary of the profile, highlighting strengths and areas for improvement. | |
Structure the output as a JSON with the following keys: | |
- "JD Match": percentage match as a string with "%" sign. | |
- "MissingKeywords": a list of missing but important keywords. | |
- "ProfileSummary": a summary as a single string. | |
Example format: | |
{{"JD Match":"85%", "MissingKeywords":["data analysis", "team leadership"], "ProfileSummary":"Highly skilled engineer with 10 years of experience in data engineering."}} | |
resume: {text} | |
description: {jd} | |
""" | |
# Streamlit app setup | |
st.title('Smart ATS') | |
st.write( | |
"Welcome! This tool helps you improve your resume's alignment with the job description, ensuring it is optimized for ATS.") | |
# Job Description input | |
jd = st.text_area("Paste the Job Description:", help="Paste the job description you want your resume to match.") | |
# Resume upload | |
uploaded_file = st.file_uploader("Upload your Resume (PDF format only):", type="pdf", | |
help="Ensure your resume is in PDF format for analysis.") | |
# Display submit button with progress | |
submit = st.button("Analyze Resume") | |
if submit: | |
if uploaded_file is not None and jd: | |
# Show loading spinner while processing | |
with st.spinner("Analyzing your resume, please wait..."): | |
text = input_pdf_text(uploaded_file) | |
response = get_gemeni_response(input_prompt.format(text=text, jd=jd)) | |
# Retry parsing up to 2 times | |
response_dict = None | |
for _ in range(2): | |
response_dict = parse_response(response) | |
if response_dict: | |
break | |
time.sleep(1) # Slight delay before retrying | |
if response_dict: | |
# Display Job Description Match | |
st.subheader("Job Description Match") | |
st.metric(label="Matching Score", value=response_dict.get("JD Match", "N/A")) | |
# Display Missing Keywords | |
st.subheader("Top Missing Keywords") | |
missing_keywords = response_dict.get("MissingKeywords", []) | |
if missing_keywords: | |
st.write(", ".join(missing_keywords)) | |
else: | |
st.write("All key terms are covered!") | |
# Display Profile Summary | |
st.subheader("Profile Summary") | |
st.text(response_dict.get("ProfileSummary", "No summary available.")) | |
# Generate downloadable report | |
st.download_button( | |
label="Download ATS Report", | |
data=json.dumps(response_dict, indent=4), | |
file_name="ATS_Analysis_Report.json", | |
mime="application/json" | |
) | |
else: | |
st.error("Error parsing response. Please try again.") | |
st.write(response) # Display raw response for debugging | |
elif not jd: | |
st.warning("Please paste a job description.") | |
else: | |
st.warning("Please upload your resume in PDF format.") | |