File size: 3,902 Bytes
eb68082 6d614b9 eb68082 6d614b9 eb68082 6d614b9 eb68082 6d614b9 eb68082 6d614b9 eb68082 6d614b9 eb68082 6d614b9 eb68082 6d614b9 eb68082 6d614b9 eb68082 6d614b9 eb68082 6d614b9 eb68082 6d614b9 eb68082 6d614b9 eb68082 6d614b9 eb68082 34c9db0 eb68082 |
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 |
# 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()
|