Abdul-Haseeb's picture
Upload app.py
90c9164 verified
import streamlit as st
import os
import re
from groq import Groq
import json
# Set up Groq client
client = Groq(api_key="")
# Define main function
def main():
st.title("AI-powered Resume Scanner")
# File upload
uploaded_file = st.file_uploader("Upload a resume", type=["pdf", "docx"])
# Job role input
job_role = st.text_input("Enter the job role")
if uploaded_file is not None and job_role:
# Process resume and get results
resume_text = parse_resume(uploaded_file)
if resume_text:
#st.write("Extracted Resume Text:")
#st.write(resume_text)
# Get resume analysis from the Groq model
name, degree, cgpa, skills, experience_score, ats_score = analyze_resume(resume_text, job_role)
# Display the results
st.write(f"**Candidate Name:** {name}")
st.write(f"**Degree:** {degree}")
st.write(f"**Latest CGPA/Percentage:** {cgpa}")
if skills:
st.write("**Skills:**")
for skill in skills:
st.write(f"- {skill}")
st.write(f"**Experience Score out of 10:** {experience_score}")
st.write(f"**ATS Score for {job_role} out of 10:** {ats_score}")
# Function to parse PDF/Word file
def parse_resume(uploaded_file):
# If PDF
if uploaded_file.type == "application/pdf":
from PyPDF2 import PdfReader
reader = PdfReader(uploaded_file)
text = ""
for page in reader.pages:
text += page.extract_text()
return text
# If Word
elif uploaded_file.type == "application/vnd.openxmlformats-officedocument.wordprocessingml.document":
from docx import Document
doc = Document(uploaded_file)
text = "\n".join([para.text for para in doc.paragraphs])
return text
else:
st.error("Unsupported file type!")
return None
# Function to analyze resume using Groq API and LLaMA 3.1
# Function to analyze resume using Groq API and LLaMA 3.1
import json
# Function to analyze resume using Groq API and LLaMA 3.1
def analyze_resume(text, job_role):
# Construct prompt for Groq API
prompt = (
f"Extract the following details from the given resume text: \n"
f"1. Candidate's Name \n"
f"2. Latest Education CGPA or Percentage \n"
f"3. List of Skills \n"
f"4. Rate experience (projects, internships) on a scale from 0 to 10 \n"
f"5. Provide an ATS score for the job role: {job_role}\n"
f"Resume Text: {text}\n"
f"Format your response in a JSON object with the following structure: \n"
f"{{\n"
f' "name": "Candidate Name",\n'
f' "Degree": "Latest Education qualification or grade:",\n'
f' "cgpa": "Latest Education CGPA or Percentage",\n'
f' "skills": ["List of skills"],\n'
f' "experience_score": "Experience Score (0 to 10)",\n'
f' "ats_score": "ATS Score for the job role"\n'
f"}}"
)
# Call Groq API for chat completion
chat_completion = client.chat.completions.create(
messages=[{"role": "user", "content": prompt}],
model="llama3-8b-8192",
temperature=0.7,
max_tokens=1024,
top_p=1,
stream=False
)
# Get the raw output from the LLM
output = chat_completion.choices[0].message.content
# Clean up the output to avoid any parsing issues
cleaned_output = re.search(r'{[^}]*}', output).group()
# Try parsing the cleaned JSON
try:
response_data = json.loads(cleaned_output)
except json.JSONDecodeError:
st.error("Failed to parse response from model.")
st.write("Model Output:")
st.write(cleaned_output)
return None, None, None, None, None
# Extract information from the parsed JSON
name = response_data.get("name", "Name not found")
degree = response_data.get("Degree", "Degree not found")
cgpa = response_data.get("cgpa", "CGPA/Percentage not found")
skills = response_data.get("skills", "Skills not found")
experience_score = response_data.get("experience_score", "Experience score not found")
ats_score = response_data.get("ats_score", "ATS score not found")
return name, degree, cgpa, skills, experience_score, ats_score
# Function to extract the candidate's name
def extract_name(text):
name_pattern = re.compile(r"(Name:?\s*)([A-Z][a-z]+(?:\s[A-Z][a-z]+)*)")
match = name_pattern.search(text)
if match:
return match.group(2)
return "Name not found"
# Function to extract CGPA or Percentage
def extract_cgpa(text):
cgpa_pattern = re.compile(r"(\bCGPA\b|\bGPA\b|\bPercentage\b):?\s*(\d+\.?\d*)")
match = cgpa_pattern.search(text)
if match:
return match.group(2)
return "CGPA/Percentage not found"
# Function to extract skills
def extract_skills(text):
skills_pattern = re.compile(r"Skills:?\s*(.*?)(?:Experience|Education|$)", re.DOTALL)
match = skills_pattern.search(text)
if match:
skills = match.group(1)
return [skill.strip() for skill in skills.split(",")]
return "Skills not found"
# Function to extract experience score
def extract_experience_score(text):
experience_pattern = re.compile(r"Experience Score:?\s*(\d{1,2})")
match = experience_pattern.search(text)
if match:
return int(match.group(1))
# Heuristic: If no explicit experience score is given, infer it based on keywords
experience_keywords = ["internship", "project", "work experience", "employment"]
experience_count = sum(text.lower().count(keyword) for keyword in experience_keywords)
return min(10, experience_count) # Cap at 10
# Function to extract ATS score
def extract_ats_score(text):
ats_pattern = re.compile(r"ATS Score:?\s*(\d+\.?\d*)")
match = ats_pattern.search(text)
if match:
return float(match.group(1))
# Heuristic to generate a score based on skill-job match
return generate_ats_score(text)
# Heuristic function to generate ATS score
def generate_ats_score(text):
# Just a dummy heuristic for now
skills = extract_skills(text)
if not skills:
return 0
required_skills = ["Python", "Machine Learning", "Data Analysis"] # Add job role specific required skills
match_count = sum(1 for skill in required_skills if skill.lower() in [s.lower() for s in skills])
return round((match_count / len(required_skills)) * 10, 2)
if __name__ == "__main__":
main()