jobspreps / app.py
aryn25's picture
Update app.py
34c9db0 verified
# 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()