| import fitz |
| import json |
| import sqlite3 |
| import requests |
| import os |
| import re |
| |
| LLM_URL = "https://unscotched-devon-interpapillary.ngrok-free.dev/generate" |
| ROOT_DIR = os.environ.get('WORKSPACE_ROOT', '.') |
| DB_PATH = os.path.join(ROOT_DIR, 'Database/personnel_data/ResumeProcessed.db') |
|
|
| os.makedirs(os.path.dirname(DB_PATH), exist_ok=True) |
|
|
| |
| def init_db(): |
| conn = sqlite3.connect(DB_PATH) |
| cursor = conn.cursor() |
| |
| cursor.execute(''' |
| CREATE TABLE IF NOT EXISTS resumes ( |
| email TEXT PRIMARY KEY, |
| education TEXT, |
| hard_skills TEXT, |
| soft_skills TEXT, |
| summary TEXT, |
| projects TEXT, |
| languages TEXT, |
| contact TEXT, |
| github TEXT, |
| linkedin TEXT, |
| brief_analysis TEXT, |
| timestamp DATETIME DEFAULT CURRENT_TIMESTAMP |
| ) |
| ''') |
| conn.commit() |
| conn.close() |
|
|
| |
| def extract_text_from_pdf(pdf_path): |
| with fitz.open(pdf_path) as doc: |
| text = "".join(page.get_text() for page in doc) |
| return text |
|
|
| |
| def call_llm(system_prompt, user_query): |
| payload = { |
| "system_prompt": system_prompt, |
| "query": user_query, |
| "max_new_tokens": 1000 |
| } |
| response = requests.post(LLM_URL, json=payload) |
| if response.status_code == 200: |
| return response.json()["response"] |
| raise Exception(f"LLM Error: {response.text}") |
|
|
| |
| def process_resume(pdf_path, user_email): |
| print(f"π Starting process for: {user_email}") |
| |
| |
| resume_raw_text = extract_text_from_pdf(pdf_path) |
| |
| |
| |
| extraction_prompt = ( |
| "You are a precise JSON extractor. Extract resume data into this EXACT JSON format: " |
| '{"education": "...", "hard_skills": "...", "soft_skills": "...", "summary": "...", ' |
| '"projects": "...", "languages": "...", "contact": "...", "github": "...", "linkedin": "..."}. ' |
| "Return ONLY the raw JSON object. Do not include any markdown or explanation." |
| ) |
| |
| try: |
| json_raw = call_llm(extraction_prompt, resume_raw_text) |
| |
| |
| json_raw = re.sub(r"```json|```", "", json_raw).strip() |
| |
| |
| |
| match = re.search(r'\{.*\}', json_raw, re.DOTALL) |
| if match: |
| json_raw = match.group(0) |
| |
| data = json.loads(json_raw) |
| |
| except Exception as e: |
| print(f"β Failed to parse LLM JSON. Raw output was: \n{json_raw[:200]}...") |
| print(f"Detailed Error: {e}") |
| return |
|
|
| |
| analysis_prompt = "Summarize the following candidate's top 3 professional strengths in 3 short sentences." |
| |
| brief_analysis = call_llm(analysis_prompt, json.dumps(data)) |
|
|
| |
| conn = sqlite3.connect(DB_PATH) |
| cursor = conn.cursor() |
| try: |
| cursor.execute(''' |
| INSERT OR REPLACE INTO resumes ( |
| email, education, hard_skills, soft_skills, summary, |
| projects, languages, contact, github, linkedin, brief_analysis |
| ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) |
| ''', ( |
| user_email, |
| str(data.get('education', 'n/a')), |
| str(data.get('hard_skills', 'n/a')), |
| str(data.get('soft_skills', 'n/a')), |
| str(data.get('summary', 'n/a')), |
| str(data.get('projects', 'n/a')), |
| str(data.get('languages', 'n/a')), |
| str(data.get('contact', 'n/a')), |
| str(data.get('github', 'n/a')), |
| str(data.get('linkedin', 'n/a')), |
| brief_analysis |
| )) |
| conn.commit() |
| print(f"β
Successfully saved profile for {user_email}") |
| except Exception as e: |
| print(f"β Database error: {e}") |
| finally: |
| conn.close() |
|
|
| |
| |
| |
| |
| |
| |
| |
| |