Spaces:
Build error
Build error
File size: 9,282 Bytes
1c39019 5019102 1c39019 5019102 3f425a8 1c39019 5019102 3f425a8 5019102 1d2b5c6 2cdc360 1c39019 5019102 1d2b5c6 1c39019 5019102 1d2b5c6 1c39019 5019102 1d2b5c6 1c39019 5019102 1c39019 5019102 1c39019 5019102 1c39019 5019102 1c39019 5019102 1c39019 5019102 1c39019 5019102 1d2b5c6 5019102 1d2b5c6 5019102 3f425a8 1c39019 5019102 1c39019 1d2b5c6 1c39019 3f425a8 1c39019 5019102 1c39019 5019102 1c39019 5019102 1c39019 5019102 1c39019 5019102 1c39019 5019102 1c39019 3f425a8 1c39019 5019102 1c39019 5019102 1c39019 5019102 1c39019 5019102 3f425a8 1c39019 5019102 3f425a8 1c39019 1d2b5c6 1c39019 1d2b5c6 1c39019 1d2b5c6 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 |
import os
import gradio as gr
import requests
import PyPDF2
import spacy
from transformers import pipeline
# Load spaCy for NER tasks
nlp = spacy.load("en_core_web_sm")
# Summarization model
summarizer = pipeline("summarization", model="facebook/bart-large-cnn")
# Sentiment analysis model
sentiment_analyzer = pipeline("sentiment-analysis", model="distilbert-base-uncased-finetuned-sst-2-english")
# Set up your Groq API endpoint and API key
GROQ_API_URL = "https://api.groq.com/v1/models/llama" # Update this if needed
GROQ_API_KEY = "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" # Replace with your actual API key
def extract_text_from_pdf(file):
"""Extract text from uploaded PDF file."""
if file is None:
return ""
try:
pdf_reader = PyPDF2.PdfReader(file)
text = ""
for page in pdf_reader.pages:
page_text = page.extract_text() or ""
text += page_text
return text
except Exception as e:
return f"Error extracting PDF text: {str(e)}"
def extract_text_from_file(file):
"""Extract text from uploaded file (PDF or TXT)."""
if file is None:
return ""
if file.name.endswith('.pdf'):
return extract_text_from_pdf(file)
elif file.name.endswith('.txt'):
return file.read().decode('utf-8')
else:
return "Unsupported file format. Please upload PDF or TXT files only."
def extract_skills(text):
"""Extract skills from text using a pre-trained NER model."""
doc = nlp(text)
skills = [ent.text for ent in doc.ents if ent.label_ == "SKILL"]
return list(set(skills))
def extract_education_and_experience(text):
"""Extract education and experience information from text using NER."""
doc = nlp(text)
education = [ent.text for ent in doc.ents if ent.label_ in ["EDUCATION", "DEGREE"]]
experience = [ent.text for ent in doc.ents if ent.label_ == "EXPERIENCE"]
return {
'education': list(set(education)),
'experience': list(set(experience))
}
def calculate_match_percentage(resume_skills, job_skills):
"""Calculate the match percentage between resume skills and job requirements."""
if not job_skills:
return 0
matching_skills = set(resume_skills).intersection(set(job_skills))
return (len(matching_skills) / len(job_skills)) * 100
def call_groq_api(prompt):
"""Call the Groq API with the prompt and return the response."""
headers = {
"Authorization": f"Bearer {GROQ_API_KEY}",
"Content-Type": "application/json"
}
payload = {
"model": "llama3-8b-8192", # Use the specified LLaMA model
"prompt": prompt,
"max_tokens": 150 # Adjust as needed
}
try:
response = requests.post(GROQ_API_URL, headers=headers, json=payload)
if response.status_code == 200:
return response.json().get("output", "No output received.")
else:
return f"API call failed with status {response.status_code}: {response.text}"
except requests.exceptions.RequestException as e:
return f"Request failed: {str(e)}"
def summarize_text(text, max_length=100):
"""Summarize the input text using the summarization model."""
return summarizer(text, max_length=max_length, min_length=30, do_sample=False)[0]['summary_text']
def sentiment_analysis(text):
"""Perform sentiment analysis on the given text."""
return sentiment_analyzer(text)[0]
def analyze_resume_and_job(resume_file, job_desc_file):
"""Main function to analyze resume and job description."""
try:
# Extract text from files
resume_text = extract_text_from_file(resume_file)
job_desc_text = extract_text_from_file(job_desc_file)
if not resume_text or not job_desc_text:
return {
"error": "Could not extract text from one or both files"
}
# Summarize resume and job description
resume_summary = summarize_text(resume_text)
job_desc_summary = summarize_text(job_desc_text)
# Perform sentiment analysis on the resume summary
resume_sentiment = sentiment_analysis(resume_summary)
# Extract information from resume
resume_skills = extract_skills(resume_text)
resume_info = extract_education_and_experience(resume_text)
# Extract information from job description
job_skills = extract_skills(job_desc_text)
job_info = extract_education_and_experience(job_desc_text)
# Calculate match percentages
skills_match = calculate_match_percentage(resume_skills, job_skills)
# Prepare input for LLaMA via Groq API
input_prompt = f"Analyze the following resume: {resume_text[:300]} and job description: {job_desc_text[:300]}."
# Call Groq API to analyze using LLaMA
llama_analysis = call_groq_api(input_prompt)
# Prepare analysis results
summary = f"""
### Summary Analysis
- Overall Skills Match: {skills_match:.1f}%
- Experience Found: {', '.join(resume_info['experience'])}
- Education Found: {', '.join(resume_info['education'])}
"""
skills = f"""
### Skills Analysis
Resume Skills:
{', '.join(resume_skills)}
Required Skills:
{', '.join(job_skills)}
Missing Skills:
{', '.join(set(job_skills) - set(resume_skills))}
"""
qualifications = f"""
### Qualifications
Education Found:
{', '.join(resume_info['education'])}
Required Education:
{', '.join(job_info['education'])}
"""
sentiment = f"""
### Sentiment Analysis
Resume Sentiment: {resume_sentiment['label']} (Confidence: {resume_sentiment['score']:.2f})
"""
# Generate recommendation based on skills match
recommendation = "Recommendation based on skills match and experience."
if skills_match >= 70:
recommendation = "Strong Match - Recommended for interview."
elif skills_match >= 50:
recommendation = "Moderate Match - Consider for interview with focus on missing skills."
else:
recommendation = "Low Match - May not meet core requirements."
recommendation = f"""
### Recommendation
{recommendation}
"""
return {
"summary": summary.strip(),
"skills": skills.strip(),
"qualifications": qualifications.strip(),
"recommendation": recommendation.strip(),
"llama_analysis": llama_analysis.strip(),
"sentiment": sentiment.strip(),
"resume_summary": resume_summary.strip(),
"job_summary": job_desc_summary.strip()
}
except Exception as e:
return {
"error": f"Analysis failed: {str(e)}"
}
# Create Gradio interface
def create_interface():
with gr.Blocks(title="Resume Analyzer", theme=gr.themes.Soft()) as demo:
gr.Markdown("# Smart Resume Analyzer")
gr.Markdown("Upload your resume and job description for instant analysis")
with gr.Row():
resume_input = gr.File(label="Upload Resume (PDF/TXT)")
job_desc_input = gr.File(label="Upload Job Description (PDF/TXT)")
analyze_button = gr.Button("Analyze")
with gr.Tabs():
with gr.TabItem("Summary"):
summary_output = gr.Markdown()
with gr.TabItem("Skills Analysis"):
skills_output = gr.Markdown()
with gr.TabItem("Qualifications"):
qualifications_output = gr.Markdown()
with gr.TabItem("Recommendation"):
recommendation_output = gr.Markdown()
with gr.TabItem("LLaMA Analysis"):
llama_output = gr.Markdown()
with gr.TabItem("Sentiment Analysis"):
sentiment_output = gr.Markdown()
with gr.TabItem("Resume Summary"):
resume_summary_output = gr.Markdown()
with gr.TabItem("Job Description Summary"):
job_summary_output = gr.Markdown()
def analyze(resume_file, job_desc_file):
if not resume_file or not job_desc_file:
return "Please upload both resume and job description."
analysis_results = analyze_resume_and_job(resume_file, job_desc_file)
summary_output.update(analysis_results.get("summary", ""))
skills_output.update(analysis_results.get("skills", ""))
qualifications_output.update(analysis_results.get("qualifications", ""))
recommendation_output.update(analysis_results.get("recommendation", ""))
llama_output.update(analysis_results.get("llama_analysis", ""))
sentiment_output.update(analysis_results.get("sentiment", ""))
resume_summary_output.update(analysis_results.get("resume_summary", ""))
job_summary_output.update(analysis_results.get("job_summary", ""))
analyze_button.click(analyze, inputs=[resume_input, job_desc_input])
return demo
# Launch Gradio app
if __name__ == "__main__":
create_interface().launch()
|