# Hugging Face Spaces-ready version of your JobPrep.AI classic resume generator # Upload resume PDF + paste job description → get AI-rewritten resume PDF import gradio as gr from transformers import pipeline, AutoTokenizer, AutoModelForSeq2SeqLM import pdfplumber from fpdf import FPDF import re import os MODEL_NAME = "MBZUAI/LaMini-Flan-T5-783M" tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME) model = AutoModelForSeq2SeqLM.from_pretrained(MODEL_NAME) generator = pipeline("text2text-generation", model=model, tokenizer=tokenizer) # Extract raw resume text from uploaded PDF def extract_text(pdf_file): with pdfplumber.open(pdf_file.name) as pdf: return "\n".join(page.extract_text() or "" for page in pdf.pages) # Extract name, email, phone, links from resume def extract_personal_info(text): name = text.strip().split("\n")[0].strip() email = re.search(r"[\w\.-]+@[\w\.-]+", text) phone = re.search(r"(\+?\d[\d\s\-\(\)]{7,})", text) links = re.findall(r"(https?://[^\s]+|www\.[^\s]+)", text) location = re.search(r"\b(Dublin|Ireland|[A-Z][a-z]+,?\s?[A-Z][a-z]+?)\b", text) return { "name": name.upper(), "contact": " | ".join(filter(None, [ email.group(0) if email else "", phone.group(0).strip() if phone else "", " | ".join(links), location.group(0) if location else "" ])) } # Rewrite section using LLM def rewrite_section(title, content, job): if not content.strip(): return "" prompt = f""" Rewrite the following section of a resume titled '{title}' to align with the job description below. Make it concise, professional, and rich in job-relevant keywords. Section: {content} Job Description: {job} """ result = generator(prompt, max_length=512, do_sample=True, top_p=0.9, temperature=0.7)[0]['generated_text'] return result.strip() # Generate and save the final resume PDF def generate_resume(pdf_file, job_description): raw_text = extract_text(pdf_file) personal = extract_personal_info(raw_text) sections = { "Professional Summary": "", "Skills": "", "Work Experience": "", "Projects": "", "Education": "", "Certifications": "", "Leadership": "" } for sec in sections.keys(): match = re.search(rf"{sec.upper()}\n(.+?)(?=\n[A-Z ]{{4,}}|\Z)", raw_text, re.DOTALL) if match: sections[sec] = match.group(1).strip() rewritten = {title: rewrite_section(title, content, job_description) for title, content in sections.items()} out_path = "final_resume.pdf" pdf = FPDF() pdf.add_page() pdf.set_auto_page_break(auto=True, margin=15) pdf.set_font("Arial", size=11) pdf.set_font("Arial", style="B", size=14) pdf.cell(200, 10, txt=personal['name'], ln=True, align="C") pdf.set_font("Arial", size=11) pdf.multi_cell(0, 10, personal['contact'], align="C") pdf.ln(5) for title, body in rewritten.items(): if not body.strip(): continue pdf.set_font("Arial", style="B", size=12) pdf.cell(200, 10, txt=title.upper(), ln=True) pdf.set_font("Arial", size=11) bullets = re.split(r"\s*-\s+", body.strip()) for bullet in bullets: bullet = bullet.strip() if bullet: pdf.multi_cell(0, 10, f"- {bullet}") pdf.ln(4) pdf.output(out_path) return out_path # Gradio Interface demo = gr.Interface( fn=generate_resume, inputs=[ gr.File(label="Upload Your Resume PDF", type="filepath"), gr.Textbox(label="Paste Job Description", lines=7, placeholder="Enter the job description here") ], outputs=gr.File(label="Download Final Resume PDF"), title="JobPrep.AI | Resume Optimizer", description="Upload your resume and tailor it instantly to any job description." ) demo.launch()