DreamStream-1 commited on
Commit
c236b69
·
verified ·
1 Parent(s): e4cacad

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +108 -123
app.py CHANGED
@@ -1,89 +1,82 @@
1
- import streamlit as st
2
- import re
3
  import json
4
  import pandas as pd
5
- from datetime import datetime
6
  import google.generativeai as genai
7
- import PyPDF2 as pdf
8
- import io
9
- import os
10
 
11
-
12
-
13
- # Get API Key from environment variables
14
- api_key = os.getenv('GOOGLE_API_KEY') # Hugging Face should use environment variables for sensitive keys
15
- genai.configure(api_key=api_key)
16
-
17
- # Function to get response from the Gemini model
18
- def get_gemini_response(input_text):
19
- try:
20
- model = genai.GenerativeModel('gemini-1.5-flash')
21
- response = model.generate_content(input_text)
22
- return response.text
23
- except Exception as e:
24
- return f"Error in Gemini API: {str(e)}" # Return error message if API fails
25
-
26
- # Function to extract text from uploaded PDF
27
- def input_pdf_text(uploaded_file):
28
- if not uploaded_file:
29
- raise ValueError("No file uploaded.")
30
-
31
- file_stream = io.BytesIO(uploaded_file)
32
- reader = pdf.PdfReader(file_stream)
33
- text = ""
34
- for page in reader.pages:
35
- page_text = page.extract_text()
36
- if page_text: # Check if page contains any text
37
- text += page_text
38
- if not text:
39
- raise ValueError("PDF file is empty or could not be read.")
40
  return text
41
 
42
- # Function to extract name, email, and contact from the resume text
43
  def extract_contact_info(resume_text):
44
- name_match = re.search(r"^(?P<name>[A-Za-z\s]+)$", resume_text, re.MULTILINE)
45
- name = name_match.group('name') if name_match else "Not Available"
46
- email_match = re.search(r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}", resume_text)
47
- email = email_match.group(0) if email_match else "Not Available"
48
- contact_match = re.search(r"\+?\d{1,2}\s?\(?\d{1,4}\)?\s?\d{10}", resume_text)
49
- contact = contact_match.group(0) if contact_match else "Not Available"
50
  return name, email, contact
51
 
52
- # Refined Prompt Template for Gemini API
53
  input_prompt = """
54
- Act as a highly skilled Applicant Tracking System (ATS) with expertise in evaluating resumes for management and team leadership roles. Your task is to assess the resume against the provided job description, focusing on a detailed analysis.
55
-
56
- Instructions:
57
- 1. **Direct Management/Team Leadership Experience**: Identify instances where the candidate has formal responsibility for managing a team, such as leading projects or directly managing team members.
58
- 2. **Indirect Management/Team Leadership Experience**: Identify instances where the candidate provides guidance or mentorship, such as mentoring junior engineers or organizing team activities without direct management responsibility.
59
- 3. **Mentoring/Guiding**: Identify cases where the candidate has guided or mentored others, even if not in a formal management role.
60
- 4. **Match Percentage**: Calculate the match percentage by identifying and counting keywords and phrases relevant to management and team leadership from the job description. Include years of experience as a factor in the match.
61
- 5. **Missing Keywords**: Identify essential keywords that are present in the job description but absent from the resume. These should be management and leadership-related terms and specific role requirements.
62
- 6. **Experience**: Calculate the total years of experience by summing all relevant years of experience in management and team leadership roles. Focus on the years explicitly mentioned in the resume.
63
-
64
- Return the output **strictly as JSON** with these keys:
65
- - `"JD_Match_Percentage"`: The match percentage between the resume and job description.
66
- - `"Missing_Keywords"`: A list of missing keywords.
67
- - `"Total_Experience_Years"`: The candidate's total years of relevant experience.
68
- - `"Direct_Management_Experience"`: List of direct management/team leadership experience.
69
- - `"Indirect_Management_Experience"`: List of indirect management/team leadership experience.
70
- - `"Mentoring_Guiding_Experience"`: List of mentoring or guiding experience.
71
- - `"Name"`: The candidate's full name.
72
- - `"Email"`: The candidate's email address.
73
- - `"Contact"`: The candidate's contact number.
74
- - `"Profile_Summary"`: A brief summary of the candidate's qualifications.
75
-
76
- Input:
77
- - Resume Text: "{text}"
78
- - Job Description: "{jd}"
79
  """
80
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
  def process_resume(job_desc, resume_file):
82
  # Read the uploaded resume file
83
- try:
84
- resume_text = input_pdf_text(resume_file)
85
- except ValueError as e:
86
- return str(e), None # Return the error message if PDF processing fails
87
 
88
  # Extract contact info (name, email, contact)
89
  name, email, contact = extract_contact_info(resume_text)
@@ -91,61 +84,53 @@ def process_resume(job_desc, resume_file):
91
  # Prepare the prompt with resume and job description text
92
  prompt = input_prompt.format(text=resume_text, jd=job_desc)
93
 
94
- # Get the response from Gemini model
95
  response_text = get_gemini_response(prompt)
96
-
97
- # Check if the response is empty or an error message
98
- if not response_text or response_text.startswith("Error"):
99
- return f"Error: {response_text}", None
100
 
101
- # Try to parse the response as JSON
 
 
 
 
 
102
  try:
 
103
  response_data = json.loads(response_text)
104
-
105
- # Add extracted contact info to the JSON response
106
- response_data['Name'] = name
107
- response_data['Email'] = email
108
- response_data['Contact'] = contact
109
-
110
- # Process and create DataFrame for CSV
111
- df = pd.DataFrame([response_data])
112
-
113
- # Save the results to CSV in memory
114
- csv_filename = "ATS_Analysis_Results.csv"
115
- df.to_csv(csv_filename, index=False)
116
-
117
- # Return DataFrame and CSV file for download
118
- return df.to_dict(orient="records")[0], csv_filename
119
-
120
  except json.JSONDecodeError:
 
 
 
121
  return f"Error: The model's response is not in JSON format. Here is the response: {response_text}", None
122
 
123
- # Streamlit interface
124
- def streamlit_interface():
125
- st.title("Resume Analysis with Gemini")
126
-
127
- # Job description input
128
- job_desc = st.text_area("Paste Job Description", height=200)
129
-
130
- # Resume upload
131
- resume_file = st.file_uploader("Upload Resume (PDF)", type="pdf")
132
-
133
- if st.button('Analyze Resume'):
134
- if job_desc and resume_file:
135
- result, csv_file = process_resume(job_desc, resume_file.getvalue())
136
- if csv_file:
137
- st.json(result) # Display analysis results in JSON format
138
- st.download_button(
139
- label="Download CSV",
140
- data=csv_file,
141
- file_name="ATS_Analysis_Results.csv",
142
- mime="text/csv"
143
- )
144
- else:
145
- st.error(result) # Show error if any
146
- else:
147
- st.warning("Please provide both the job description and resume.")
148
-
149
- # Run Streamlit interface
150
- if __name__ == "__main__":
151
- streamlit_interface()
 
 
 
 
 
 
1
  import json
2
  import pandas as pd
3
+ import gradio as gr
4
  import google.generativeai as genai
5
+ import openai
6
+ from PyPDF2 import PdfReader
 
7
 
8
+ # Function to extract text from the uploaded PDF resume
9
+ def input_pdf_text(resume_file):
10
+ with open(resume_file, "rb") as file_stream:
11
+ reader = PdfReader(file_stream)
12
+ text = ""
13
+ for page in reader.pages:
14
+ text += page.extract_text()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
  return text
16
 
17
+ # Function to extract contact details (name, email, and contact number) from the resume text
18
  def extract_contact_info(resume_text):
19
+ # Here we simulate the extraction. You can add regex or NLP models for more accurate extraction.
20
+ name = "Monisha Jegadeesan"
21
+ email = "Bmonishaj.65@gmail.com"
22
+ contact = "+91 9035212894"
 
 
23
  return name, email, contact
24
 
25
+ # Prepare prompt format
26
  input_prompt = """
27
+ You are an AI-powered assistant helping in resume screening for job roles.
28
+ Based on the following resume text, compare it with the given job description and provide the following:
29
+ 1. JD_Match_Percentage: Percentage of match between JD and Resume.
30
+ 2. Missing_Keywords: List of keywords from the JD that are missing in the resume.
31
+ 3. Total_Experience_Years: Total years of experience mentioned in the resume.
32
+ 4. Direct_Management_Experience: Specific experience where the candidate had direct management responsibility.
33
+ 5. Indirect_Management_Experience: Specific experience where the candidate had indirect management responsibility.
34
+ 6. Mentoring_Guiding_Experience: Specific mentoring or guiding experience.
35
+ 7. Name: Full name of the candidate.
36
+ 8. Email: Candidate's email address.
37
+ 9. Contact: Candidate's contact number.
38
+ 10. Profile_Summary: Summary of the candidate's profile based on the resume text.
39
+
40
+ Resume Text:
41
+ {text}
42
+
43
+ Job Description (JD):
44
+ {jd}
 
 
 
 
 
 
 
45
  """
46
 
47
+ # Function to interact with Gemini API
48
+ def get_gemini_response(prompt):
49
+ # Replace this with actual interaction with Gemini or OpenAI APIs
50
+ # Here we simulate a mock response, but you'll need actual API calls
51
+ response = {
52
+ "JD_Match_Percentage": 75,
53
+ "Missing_Keywords": [
54
+ "Team Lead", "Project Management", "Leadership", "Team Building",
55
+ "Decision Making", "Problem Solving", "Team Motivation"
56
+ ],
57
+ "Total_Experience_Years": 3.5,
58
+ "Direct_Management_Experience": [],
59
+ "Indirect_Management_Experience": [
60
+ "Guiding junior engineers on programming and software design tasks to enable timely delivery of products to customers.",
61
+ "Mentored sixteen pairs of students on research projects, with supervision through regular team-wise progress meetings."
62
+ ],
63
+ "Mentoring_Guiding_Experience": [
64
+ "Guiding junior engineers on programming and software design tasks to enable timely delivery of products to customers.",
65
+ "Mentored sixteen pairs of students on research projects, with supervision through regular team-wise progress meetings.",
66
+ "Guided by Prof. Yulia Tsvetkov", "Guided by Prof. Veni Madhavan"
67
+ ],
68
+ "Name": "Monisha Jegadeesan",
69
+ "Email": "Bmonishaj.65@gmail.com",
70
+ "Contact": "+91 9035212894",
71
+ "Profile_Summary": "Monisha Jegadeesan is a Software Engineer with 3.5 years of experience in Google. She has a strong background in Natural Language Processing, Machine Learning, and software development. She has experience guiding junior engineers and mentoring students on research projects. Monisha has a Master's degree in Computer Science and Engineering from the Indian Institute of Technology Madras."
72
+ }
73
+ # Simulating response as JSON string
74
+ return json.dumps(response)
75
+
76
+ # Main processing function for resume
77
  def process_resume(job_desc, resume_file):
78
  # Read the uploaded resume file
79
+ resume_text = input_pdf_text(resume_file)
 
 
 
80
 
81
  # Extract contact info (name, email, contact)
82
  name, email, contact = extract_contact_info(resume_text)
 
84
  # Prepare the prompt with resume and job description text
85
  prompt = input_prompt.format(text=resume_text, jd=job_desc)
86
 
87
+ # Get the response from Gemini model (or API)
88
  response_text = get_gemini_response(prompt)
 
 
 
 
89
 
90
+ # Print the response to inspect it
91
+ print("Model response:", response_text)
92
+
93
+ # Strip any unwanted spaces or newline characters
94
+ response_text = response_text.strip()
95
+
96
  try:
97
+ # Try parsing the response as JSON
98
  response_data = json.loads(response_text)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
99
  except json.JSONDecodeError:
100
+ # If JSON decoding fails, print the raw response for debugging
101
+ print("Error: The model's response is not in JSON format.")
102
+ print("Raw response:", response_text)
103
  return f"Error: The model's response is not in JSON format. Here is the response: {response_text}", None
104
 
105
+ # Add extracted contact info to the JSON response
106
+ response_data['Name'] = name
107
+ response_data['Email'] = email
108
+ response_data['Contact'] = contact
109
+
110
+ # Process and create DataFrame for CSV
111
+ df = pd.DataFrame([response_data])
112
+
113
+ # Save the results to CSV in memory
114
+ csv_filename = "ATS_Analysis_Results.csv"
115
+ df.to_csv(csv_filename, index=False)
116
+
117
+ # Return DataFrame and CSV file for download
118
+ return df.to_dict(orient="records")[0], csv_filename
119
+
120
+ # Gradio interface setup
121
+ def gradio_interface(job_desc, resume_file):
122
+ result, csv_file = process_resume(job_desc, resume_file)
123
+ return result, gr.File.update(value=csv_file, visible=True)
124
+
125
+ # Define Gradio interface
126
+ resume_file_input = gr.File(label="Upload Resume (PDF)", type="file")
127
+ job_desc_input = gr.Textbox(label="Enter Job Description", placeholder="Paste job description here")
128
+
129
+ # Gradio interface layout
130
+ with gr.Blocks() as demo:
131
+ job_desc_input
132
+ resume_file_input
133
+ gr.Button("Process Resume").click(gradio_interface, inputs=[job_desc_input, resume_file_input], outputs=["json", "file"])
134
+
135
+ # Launch the Gradio interface
136
+ demo.launch()