Coder19/interview_system
0
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 