Spaces:
Running
Running
Johnny
updated resume_format > template, hide sidebar, download Spacy model with spacy_loader.py
102e49d
# utils/reporting.py | |
import re | |
import fitz # PyMuPDF | |
from io import BytesIO | |
from config import supabase, embedding_model, client, query | |
from .screening import evaluate_resumes | |
def generate_pdf_report(shortlisted_candidates, questions=None): | |
""" | |
Creates a PDF report summarizing top candidates and interview questions. | |
""" | |
pdf = BytesIO() | |
doc = fitz.open() | |
for candidate in shortlisted_candidates: | |
page = doc.new_page() | |
info = ( | |
f"Candidate: {candidate['name']}\n" | |
f"Email: {candidate['email']}\n" | |
f"Score: {candidate['score']}\n\n" | |
f"Summary:\n{candidate.get('summary', 'No summary available')}" | |
) | |
page.insert_textbox(fitz.Rect(50, 50, 550, 750), info, fontsize=11, fontname="helv", align=0) | |
if questions: | |
q_page = doc.new_page() | |
q_text = "Suggested Interview Questions:\n\n" + "\n".join(questions) | |
q_page.insert_textbox(fitz.Rect(50, 50, 550, 750), q_text, fontsize=11, fontname="helv", align=0) | |
doc.save(pdf) | |
pdf.seek(0) | |
return pdf | |
def generate_interview_questions_from_summaries(candidates): | |
if not isinstance(candidates, list): | |
raise TypeError("Expected a list of candidate dictionaries.") | |
summaries = " ".join(c.get("summary", "") for c in candidates) | |
prompt = ( | |
"Based on the following summary of a top candidate for a job role, " | |
"generate 5 thoughtful, general interview questions that would help a recruiter assess their fit:\n\n" | |
f"{summaries}" | |
) | |
try: | |
response = client.chat.completions.create( | |
model="tgi", | |
messages=[{"role": "user", "content": prompt}], | |
temperature=0.7, | |
max_tokens=500, | |
) | |
result = response.choices[0].message.content | |
# Clean and normalize questions | |
raw_questions = result.split("\n") | |
questions = [] | |
for q in raw_questions: | |
q = q.strip() | |
# Skip empty lines and markdown headers | |
if not q or re.match(r"^#+\s*", q): | |
continue | |
# Remove leading bullets like "1.", "1)", "- 1.", etc. | |
q = re.sub(r"^(?:[-*]?\s*)?(?:Q?\d+[\.\)\-]?\s*)+", "", q) | |
# Remove markdown bold/italics (**, *, etc.) | |
q = re.sub(r"[*_]+", "", q) | |
# Remove duplicate trailing punctuation | |
q = q.strip(" .") | |
questions.append(q.strip()) | |
return [f"Q{i+1}. {q}" for i, q in enumerate(questions[:5])] or ["⚠️ No questions generated."] | |
except Exception as e: | |
print(f"❌ Error generating interview questions: {e}") | |
return ["⚠️ Error generating questions."] |