Team Ai
Apppublic

Coder19/interview_system

sourceHugging Faceupdated 1y agoView on Hugging Face
0likes
resume.py121 linesDownload Raw Back to api
1from fastapi import APIRouter2from fastapi.responses import StreamingResponse3from interview_prep.resume_creation import generate_resume_from_prompt4from fpdf import FPDF5from io import BytesIO6import re7 8router = APIRouter()9 10def parse_resume_text(resume_text: str):11    # Clean up Markdown symbols12    cleaned_text = re.sub(r'[*#]+', '', resume_text).strip()13 14    # Section aliases15    section_aliases = {16        "name": "Name",17        "contact": "Contact Info",18        "contact info": "Contact Info",19        "contact information": "Contact Info",20        "objective": "Objective",21        "skills": "Skills",22        "experience": "Experience",23        "work experience": "Experience",24        "education": "Education",25        "projects": "Projects"26    }27 28    section_pattern = re.compile(29        r'^(Name|Contact Info|Contact Information|Objective|Skills|Experience|Work Experience|Education|Projects)\s*[:\-]?\s*$',30        re.IGNORECASE31    )32 33    resume_dict = {}34    current_section = None35 36    for line in cleaned_text.splitlines():37        line = line.strip()38        if not line:39            continue40 41        # Match section headers42        match = section_pattern.match(line)43        if match:44            key = match.group(1).lower()45            current_section = section_aliases.get(key, key.title())46            resume_dict[current_section] = ""47            continue48 49        # Append content under current section50        if current_section:51            resume_dict[current_section] += line + "\n"52 53    # Safety: return raw text if parsing fails54    if not resume_dict:55        return {"RawText": resume_text}56 57    return resume_dict58 59 60class ResumePDF(FPDF):61    def __init__(self):62        super().__init__()63        self.set_auto_page_break(auto=True, margin=15)64        self.add_page()65        self.set_font("Arial", size=12)66 67    def build_resume(self, data):68        self.set_font("Arial", 'B', 16)69        name = data.get("Name", "John Doe").strip()70        self.cell(200, 10, txt=name, ln=True, align='C')71 72        self.set_font("Arial", '', 12)73        contact = data.get("Contact Info", "email@example.com | +1 234 567 890").strip()74        self.cell(200, 10, txt=contact, ln=True, align='C')75 76        self.ln(10)77 78        for section in ["Objective", "Skills", "Experience", "Education", "Projects"]:79            content = data.get(section)80            if content:81                self.set_font("Arial", 'B', 14)82                self.cell(200, 10, section, ln=True)83                self.set_font("Arial", '', 12)84                self.multi_cell(0, 10, content.strip())85                self.ln(5)86 87 88@router.post("/generate-resume")89async def generate_resume(payload: dict):90    prompt = payload.get("prompt")91    if not prompt:92        return {"error": "Prompt is required."}93 94    # Step 1: Generate Resume Text95    resume_text = generate_resume_from_prompt(prompt)96    print("\n--- Resume TEXT from OpenAI ---\n", resume_text)97 98    # Step 2: Parse Resume Text99    resume_data = parse_resume_text(resume_text)100    print("\n--- Parsed Resume Data ---\n", resume_data)101 102    if not resume_data:103        return {"error": "Unable to parse resume text. Please use a proper format."}104 105    # Step 3: Generate PDF106    pdf = ResumePDF()107    pdf.build_resume(resume_data)108 109    pdf_bytes = pdf.output(dest='S').encode('latin1')110    pdf_buffer = BytesIO(pdf_bytes)111 112 113    # Step 4: Stream as response114    115 116    return StreamingResponse(117        pdf_buffer,118        media_type="application/pdf",119        headers={"Content-Disposition": "attachment; filename=resume.pdf"}120    )121