TalentFinderAI / app.py
rajeshthangaraj1's picture
Update app.py
d3a5c31 verified
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.")