import gradio as gr import fitz import docx from sentence_transformers import SentenceTransformer, util from gtts import gTTS import tempfile # Load the model model = SentenceTransformer("all-MiniLM-L6-v2") # Define a multi-domain skill set top_skills = [ # Tech "Python", "JavaScript", "SQL", "Machine Learning", "AWS", "Docker", "React", # Marketing "SEO", "Content Creation", "Brand Management", "Google Analytics", "Social Media Marketing", # Finance "Financial Analysis", "Accounting", "Risk Management", # Healthcare "Patient Care", "Diagnosis", "Treatment Planning", # Education "Lesson Planning", "Curriculum Design", "Classroom Management", # Soft Skills "Communication", "Leadership", "Teamwork", "Problem Solving", "Critical Thinking" ] # Job mapping job_roles = [ ("Data Analyst", {"Python", "SQL", "Data Analysis"}), ("Frontend Developer", {"JavaScript", "React"}), ("Backend Developer", {"Python", "Docker", "AWS"}), ("Machine Learning Engineer", {"Machine Learning", "Python"}), ("Marketing Manager", {"SEO", "Content Creation", "Brand Management"}), ("Digital Marketer", {"Google Analytics", "Social Media Marketing", "Content Creation"}), ("Financial Analyst", {"Financial Analysis", "Accounting"}), ("Risk Manager", {"Risk Management", "Accounting"}), ("Nurse", {"Patient Care", "Diagnosis"}), ("Healthcare Administrator", {"Treatment Planning", "Leadership"}), ("Teacher", {"Lesson Planning", "Classroom Management"}), ("Project Manager", {"Leadership", "Project Management"}) ] def extract_text_from_pdf(pdf_file): doc = fitz.open(pdf_file) text = "" for page in doc: text += page.get_text() return text def extract_text_from_docx(docx_file): doc = docx.Document(docx_file) return "\n".join([p.text for p in doc.paragraphs]) def detect_skills(text): sentences = [s.strip() for s in text.split(".") if len(s.strip()) > 5] if not sentences: return [], [] sentence_embeddings = model.encode(sentences, convert_to_tensor=True) skill_embeddings = model.encode(top_skills, convert_to_tensor=True) cosine_scores = util.cos_sim(skill_embeddings, sentence_embeddings) found_skills = [] for idx, skill in enumerate(top_skills): score = max(cosine_scores[idx]) if score > 0.4: found_skills.append(skill) missing_skills = [s for s in top_skills if s not in found_skills] return found_skills, missing_skills def suggest_jobs(found_skills): matched_jobs = [] skill_set = set(found_skills) scored_jobs = [] for title, required_skills in job_roles: matches = skill_set & required_skills score = len(matches) / len(required_skills) # proportion matched if score > 0: # at least one skill matched scored_jobs.append((title, score)) if scored_jobs: scored_jobs.sort(key=lambda x: x[1], reverse=True) matched_jobs = [title for title, _ in scored_jobs[:3]] else: matched_jobs = ["General Roles"] return matched_jobs def recommend_skills(found_skills, matched_jobs): skill_set = set(found_skills) if matched_jobs == ["General Roles"]: return [s for s in top_skills if s not in skill_set][:5] relevant_skills = set() for job, required_skills in job_roles: if job in matched_jobs: relevant_skills |= required_skills missing_in_domain = [s for s in relevant_skills if s not in skill_set] if len(missing_in_domain) < 5: others = [s for s in top_skills if s not in skill_set and s not in missing_in_domain] missing_in_domain.extend(others[:5 - len(missing_in_domain)]) return missing_in_domain[:5] def summarize_resume(found_skills): if not found_skills: return "No clear skills detected in resume." return "This resume highlights skills in " + ", ".join(found_skills) + "." def score_resume(found_skills): score = int(len(found_skills) / len(top_skills) * 100) return min(score, 100) def save_report(text, skills, jobs, missing, summary, score): report = f""" --- Resume Analysis Report --- Summary: {summary} Resume Text: {text} Detected Skills: {skills} Suggested Job Titles: {jobs} Recommended Skills to Learn: {missing} Resume Score: {score}/100 """ tmp = tempfile.NamedTemporaryFile(delete=False, suffix=".txt", mode='w', encoding='utf-8') tmp.write(report) tmp.close() return tmp.name def text_to_speech(jobs): tts = gTTS(f"Based on your resume, recommended job titles are: {jobs}") tmp = tempfile.NamedTemporaryFile(delete=False, suffix=".mp3") tts.save(tmp.name) return tmp.name def process_resume(file_obj): filename = file_obj.name ext = filename.split(".")[-1].lower() if ext == "pdf": resume_text = extract_text_from_pdf(filename) elif ext == "txt": resume_text = file_obj.read().decode("utf-8") elif ext == "docx": resume_text = extract_text_from_docx(filename) else: return "Unsupported file format", "", "", "", "", "", None, None found_skills, _ = detect_skills(resume_text) matched_jobs = suggest_jobs(found_skills) recommended = recommend_skills(found_skills, matched_jobs) summary = summarize_resume(found_skills) skills_str = ", ".join(found_skills) jobs_str = ", ".join(matched_jobs) missing_str = ", ".join(recommended) score = score_resume(found_skills) report_path = save_report(resume_text, skills_str, jobs_str, missing_str, summary, score) audio_path = text_to_speech(jobs_str) return resume_text, summary, skills_str, jobs_str, missing_str, f"{score}/100", report_path, audio_path # Build the UI with gr.Blocks(theme="soft") as demo: gr.Markdown(""" # 📄✨ Resume Analyzer & Job Matcher Upload your **resume** and let AI analyze it for: - 🧠 **Summary of your profile** - ✅ Detected **skills** - 💼 Suggested **job titles** - 🚀 Recommended **skills to learn** - 🎯 **Resume score** - 🔊 Audio feedback - 📄 Downloadable report Supported formats: `.pdf`, `.docx`, `.txt` """) with gr.Row(): with gr.Column(): file = gr.File(label="📤 Upload your resume here") btn = gr.Button("🚀 Analyze Resume", elem_classes="analyze-btn") with gr.Tabs(): with gr.Tab("📋 Resume Text"): resume_text = gr.Textbox(label="Your Resume Text", lines=15, interactive=False) with gr.Tab("🧠 Summary"): summary = gr.Textbox(label="Resume Summary", interactive=False) with gr.Tab("🧰 Skills & Jobs"): skills = gr.Textbox(label="Detected Skills", interactive=False) jobs = gr.Textbox(label="Suggested Job Titles", interactive=False) missing = gr.Textbox(label="Recommended Skills to Learn", interactive=False) with gr.Tab("📊 Score"): score = gr.Textbox(label="Resume Score", interactive=False) with gr.Tab("📄 Download & 🔊 Audio"): report = gr.File(label="📄 Download Analysis Report") audio = gr.Audio(label="🔊 Job Titles Audio") btn.click( fn=process_resume, inputs=file, outputs=[ resume_text, summary, skills, jobs, missing, score, report, audio ] ) if __name__ == "__main__": demo.launch()