Ai-Resume-Ranking / core /jd_processor.py
yhng2525's picture
Upload 15 files
1595f22 verified
# %%writefile core/jd_processor.py
import logging
import json
import os
from openai import OpenAI, APIError
from utils.prompts import JD_PROMPT
logger = logging.getLogger(__name__)
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
def generate_jd_rubric(jd_text, max_retries=3):
"""Generate JD rubric with retry logic and better error handling."""
for attempt in range(max_retries):
try:
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{"role": "system", "content": "You are an experienced HR Talent Manager AI assistant. Your specialty is analyzing job descriptions and creating structured hiring rubrics."},
{"role": "user", "content": JD_PROMPT.format(jd_text=jd_text)}
],
temperature=0.2,
response_format={"type": "json_object"} # New: Force JSON response
)
content = response.choices[0].message.content
logger.debug(f"LLM response (attempt {attempt+1}): {content[:200]}...")
# Parse JSON
jd_data = json.loads(content) # No need for find() with response_format
# Validate structure
required_keys = {"role_title", "must_have_skills", "nice_to_have_skills",
"soft_skills", "minimum_years_experience", "recommended_weights"}
if not all(key in jd_data for key in required_keys):
raise ValueError("Missing required keys in response")
return jd_data
except json.JSONDecodeError as e:
logger.warning(f"JSON decode failed (attempt {attempt+1}): {e}")
if attempt == max_retries - 1:
return get_empty_template()
except APIError as e:
logger.error(f"OpenAI API error: {e}")
if attempt == max_retries - 1:
return get_empty_template()
except Exception as e:
logger.error(f"Unexpected error: {e}")
return get_empty_template()
return get_empty_template()
def get_empty_template():
"""Return empty rubric template."""
return {
"role_title": "",
"must_have_skills": [],
"nice_to_have_skills": [],
"soft_skills": [],
"minimum_years_experience": 0,
"recommended_weights": {}
}