rajeshthangaraj1 commited on
Commit
d3a5c31
1 Parent(s): bfd4ce4

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +80 -30
app.py CHANGED
@@ -3,7 +3,9 @@ import google.generativeai as genai
3
  import os
4
  import PyPDF2 as pdf
5
  from dotenv import load_dotenv
6
- import json # Import json module for safe parsing
 
 
7
 
8
  load_dotenv()
9
  genai.configure(api_key=os.getenv('GOOGLE_API_KEY'))
@@ -24,47 +26,95 @@ def input_pdf_text(upload_file):
24
  return text
25
 
26
 
27
- # Prompt engineering
 
 
 
 
 
 
 
 
 
 
 
28
  input_prompt = """
29
- hey Act like a skilled or very experienced ATS (Application Tracking System) with a deep understanding of tech field, software engineering,
30
- data science, data analytics, and big data engineering. Your task is to evaluate the resume based on the given job description. You must
31
- consider the job market is very competitive and provide the best assistance for improving the resume. Assign the percentage
32
- Matching based on JD (Job Description) and the missing keywords with high accuracy.
 
 
 
 
 
 
 
 
 
33
  resume: {text}
34
  description: {jd}
35
-
36
- I want the response in a structured JSON format like this:
37
- {{"JD Match":"%", "MissingKeywords":[], "Profile Summary":""}}
38
  """
39
 
40
  # Streamlit app setup
41
  st.title('Smart ATS')
42
- st.text("Improve your Resume ATS")
43
- jd = st.text_area("Paste the Job Description")
44
- uploaded_file = st.file_uploader("Upload your Resume", type="pdf", help="Please upload your resume in PDF format")
45
- submit = st.button("Submit")
 
 
 
 
 
 
 
 
46
 
47
  if submit:
48
- if uploaded_file is not None:
49
- text = input_pdf_text(uploaded_file)
50
- response = get_gemeni_response(input_prompt.format(text=text, jd=jd))
 
 
51
 
52
- try:
53
- # Parse the response using json.loads
54
- response_dict = json.loads(response) # Use json.loads instead of eval
 
 
 
 
55
 
56
- # Display structured output
57
- st.subheader("Job Description Match")
58
- st.write(f"{response_dict['JD Match']}")
 
59
 
60
- st.subheader("Missing Keywords")
61
- st.write(", ".join(response_dict["MissingKeywords"]))
 
 
 
 
 
62
 
63
- st.subheader("Profile Summary")
64
- st.text(response_dict["Profile Summary"])
 
65
 
66
- except json.JSONDecodeError:
67
- st.error("Error parsing response. Check the response format.")
68
- st.write(response) # Display raw response for debugging
 
 
 
 
 
 
 
 
 
 
69
  else:
70
- st.warning("Please upload your resume.")
 
3
  import os
4
  import PyPDF2 as pdf
5
  from dotenv import load_dotenv
6
+ import json
7
+ import re
8
+ import time
9
 
10
  load_dotenv()
11
  genai.configure(api_key=os.getenv('GOOGLE_API_KEY'))
 
26
  return text
27
 
28
 
29
+ def parse_response(response):
30
+ """Validate and parse JSON response string."""
31
+ # Ensure response is JSON-like with regex before parsing
32
+ if re.match(r'^\{.*\}$', response.strip(), re.DOTALL):
33
+ try:
34
+ return json.loads(response)
35
+ except json.JSONDecodeError:
36
+ return None
37
+ return None
38
+
39
+
40
+ # Enhanced Prompt Engineering
41
  input_prompt = """
42
+ Act as a highly skilled ATS (Applicant Tracking System) expert with strong knowledge of software engineering, data science, analytics, and big data engineering.
43
+ Your goal is to analyze the resume content and compare it to the provided job description. Provide the following:
44
+ 1. An overall Job Description (JD) Match percentage.
45
+ 2. Top missing keywords or phrases relevant to the job description.
46
+ 3. A summary of the profile, highlighting strengths and areas for improvement.
47
+
48
+ Structure the output as a JSON with the following keys:
49
+ - "JD Match": percentage match as a string with "%" sign.
50
+ - "MissingKeywords": a list of missing but important keywords.
51
+ - "ProfileSummary": a summary as a single string.
52
+
53
+ Example format:
54
+ {{"JD Match":"85%", "MissingKeywords":["data analysis", "team leadership"], "ProfileSummary":"Highly skilled engineer with 10 years of experience in data engineering."}}
55
  resume: {text}
56
  description: {jd}
 
 
 
57
  """
58
 
59
  # Streamlit app setup
60
  st.title('Smart ATS')
61
+ st.write(
62
+ "Welcome! This tool helps you improve your resume's alignment with the job description, ensuring it is optimized for ATS.")
63
+
64
+ # Job Description input
65
+ jd = st.text_area("Paste the Job Description:", help="Paste the job description you want your resume to match.")
66
+
67
+ # Resume upload
68
+ uploaded_file = st.file_uploader("Upload your Resume (PDF format only):", type="pdf",
69
+ help="Ensure your resume is in PDF format for analysis.")
70
+
71
+ # Display submit button with progress
72
+ submit = st.button("Analyze Resume")
73
 
74
  if submit:
75
+ if uploaded_file is not None and jd:
76
+ # Show loading spinner while processing
77
+ with st.spinner("Analyzing your resume, please wait..."):
78
+ text = input_pdf_text(uploaded_file)
79
+ response = get_gemeni_response(input_prompt.format(text=text, jd=jd))
80
 
81
+ # Retry parsing up to 2 times
82
+ response_dict = None
83
+ for _ in range(2):
84
+ response_dict = parse_response(response)
85
+ if response_dict:
86
+ break
87
+ time.sleep(1) # Slight delay before retrying
88
 
89
+ if response_dict:
90
+ # Display Job Description Match
91
+ st.subheader("Job Description Match")
92
+ st.metric(label="Matching Score", value=response_dict.get("JD Match", "N/A"))
93
 
94
+ # Display Missing Keywords
95
+ st.subheader("Top Missing Keywords")
96
+ missing_keywords = response_dict.get("MissingKeywords", [])
97
+ if missing_keywords:
98
+ st.write(", ".join(missing_keywords))
99
+ else:
100
+ st.write("All key terms are covered!")
101
 
102
+ # Display Profile Summary
103
+ st.subheader("Profile Summary")
104
+ st.text(response_dict.get("ProfileSummary", "No summary available."))
105
 
106
+ # Generate downloadable report
107
+ st.download_button(
108
+ label="Download ATS Report",
109
+ data=json.dumps(response_dict, indent=4),
110
+ file_name="ATS_Analysis_Report.json",
111
+ mime="application/json"
112
+ )
113
+ else:
114
+ st.error("Error parsing response. Please try again.")
115
+ st.write(response) # Display raw response for debugging
116
+
117
+ elif not jd:
118
+ st.warning("Please paste a job description.")
119
  else:
120
+ st.warning("Please upload your resume in PDF format.")