arundh987 commited on
Commit
1defc09
·
verified ·
1 Parent(s): ef94cd3

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +46 -40
app.py CHANGED
@@ -3,23 +3,26 @@ import re
3
  from typing import Tuple, List
4
  import gradio as gr
5
 
6
- # -----------------------------
7
  # Config
8
- # -----------------------------
9
  OPENAI_API_KEY = os.getenv("OPENAI_API_KEY", "")
10
  USE_OPENAI = bool(OPENAI_API_KEY)
11
 
 
 
 
 
12
  if USE_OPENAI:
13
  try:
14
  from openai import OpenAI
15
  oai_client = OpenAI(api_key=OPENAI_API_KEY)
16
- OAI_MODEL = "gpt-4o-mini"
17
  except Exception:
18
  USE_OPENAI = False
19
 
20
- # -----------------------------
21
  # Helpers
22
- # -----------------------------
23
  def normalize_text(t: str) -> str:
24
  return re.sub(r"\s+", " ", (t or "").strip())
25
 
@@ -35,25 +38,31 @@ def keyword_match_score(resume: str, jd: str) -> Tuple[float, List[str]]:
35
  score = 100.0 * len(overlap) / max(1, len(j_set))
36
  return round(score, 1), overlap[:30]
37
 
38
- def call_openai(system_prompt: str, user_prompt: str) -> str:
39
- if not USE_OPENAI:
 
40
  return ""
41
- try:
42
- resp = oai_client.chat.completions.create(
43
- model=OAI_MODEL,
44
- messages=[
45
- {"role": "system", "content": system_prompt},
46
- {"role": "user", "content": user_prompt},
47
- ],
48
- temperature=0.5,
49
- )
50
- return resp.choices[0].message.content.strip()
51
- except Exception:
52
- return "(Note: OpenAI call failed; using mock output.)"
53
-
54
- # -----------------------------
 
 
 
 
 
55
  # Prompts
56
- # -----------------------------
57
  SYS_BASE = (
58
  "You are CareerForge, a concise, supportive career assistant. "
59
  "Prioritize clarity, actionability, fairness, and transparency. "
@@ -105,9 +114,9 @@ BIAS_REFLECTION = (
105
  "Limitations: Human review is always essential."
106
  )
107
 
108
- # -----------------------------
109
  # Core Functions
110
- # -----------------------------
111
  def ingest_inputs(jd_text: str, resume_text: str):
112
  jd_clean = normalize_text(jd_text)
113
  resume_clean = normalize_text(resume_text)
@@ -118,10 +127,9 @@ def ingest_inputs(jd_text: str, resume_text: str):
118
  def generate_improvements(jd_clean: str, resume_clean: str):
119
  if not jd_clean or not resume_clean:
120
  return "Please provide both Job Description and Resume."
121
- if USE_OPENAI:
122
- out = call_openai(SYS_BASE, prompt_resume_improvements(resume_clean, jd_clean))
123
- if out:
124
- return out
125
  # Mock fallback
126
  score, matched = keyword_match_score(resume_clean, jd_clean)
127
  return (
@@ -137,10 +145,9 @@ def generate_improvements(jd_clean: str, resume_clean: str):
137
  def generate_cover_letter(jd_clean: str, resume_clean: str):
138
  if not jd_clean or not resume_clean:
139
  return "Please provide both Job Description and Resume."
140
- if USE_OPENAI:
141
- out = call_openai(SYS_BASE, prompt_cover_letter(resume_clean, jd_clean))
142
- if out:
143
- return out
144
  return (
145
  "(Mock Cover Letter)\n"
146
  "Dear Hiring Manager,\n\n"
@@ -154,10 +161,9 @@ def generate_cover_letter(jd_clean: str, resume_clean: str):
154
  def generate_mock_interview(jd_clean: str, resume_clean: str, style: str):
155
  if not jd_clean or not resume_clean:
156
  return "Please provide both Job Description and Resume."
157
- if USE_OPENAI:
158
- out = call_openai(SYS_BASE, prompt_mock_interview(resume_clean, jd_clean, style))
159
- if out:
160
- return out
161
  return (
162
  f"(Mock {style} Interview)\n\n"
163
  "Q1: Tell me about a project relevant to this role.\n"
@@ -177,15 +183,15 @@ def generate_mock_interview(jd_clean: str, resume_clean: str, style: str):
177
  "Tip: Reference 1–2 specifics from the JD."
178
  )
179
 
180
- # -----------------------------
181
  # Demo Defaults
182
- # -----------------------------
183
  DEMO_JD = "Responsibilities: Collaborate, improve processes, analyze metrics. Preferred: Python, SQL."
184
  DEMO_RESUME = "Experience: Assisted in process improvement; created reports. Skills: Python, SQL, Excel."
185
 
186
- # -----------------------------
187
  # UI
188
- # -----------------------------
189
  with gr.Blocks(title="CareerForge — Resume & Interview Coach") as demo:
190
  gr.Markdown("# CareerForge — Resume & Interview Coach")
191
  gr.Markdown(
 
3
  from typing import Tuple, List
4
  import gradio as gr
5
 
6
+ # =============================
7
  # Config
8
+ # =============================
9
  OPENAI_API_KEY = os.getenv("OPENAI_API_KEY", "")
10
  USE_OPENAI = bool(OPENAI_API_KEY)
11
 
12
+ # Prefer the most reliable model first, with fallbacks
13
+ PREFERRED_MODELS = ["gpt-4o", "gpt-4o-mini", "gpt-3.5-turbo"]
14
+
15
+ oai_client = None
16
  if USE_OPENAI:
17
  try:
18
  from openai import OpenAI
19
  oai_client = OpenAI(api_key=OPENAI_API_KEY)
 
20
  except Exception:
21
  USE_OPENAI = False
22
 
23
+ # =============================
24
  # Helpers
25
+ # =============================
26
  def normalize_text(t: str) -> str:
27
  return re.sub(r"\s+", " ", (t or "").strip())
28
 
 
38
  score = 100.0 * len(overlap) / max(1, len(j_set))
39
  return round(score, 1), overlap[:30]
40
 
41
+ def call_openai_with_fallback(system_prompt: str, user_prompt: str) -> str:
42
+ """Try several models; return first successful response or empty string."""
43
+ if not (USE_OPENAI and oai_client):
44
  return ""
45
+ for model in PREFERRED_MODELS:
46
+ try:
47
+ resp = oai_client.chat.completions.create(
48
+ model=model,
49
+ messages=[
50
+ {"role": "system", "content": system_prompt},
51
+ {"role": "user", "content": user_prompt},
52
+ ],
53
+ temperature=0.5,
54
+ )
55
+ content = resp.choices[0].message.content
56
+ if content:
57
+ return content.strip()
58
+ except Exception:
59
+ # Try next model in the list
60
+ continue
61
+ return ""
62
+
63
+ # =============================
64
  # Prompts
65
+ # =============================
66
  SYS_BASE = (
67
  "You are CareerForge, a concise, supportive career assistant. "
68
  "Prioritize clarity, actionability, fairness, and transparency. "
 
114
  "Limitations: Human review is always essential."
115
  )
116
 
117
+ # =============================
118
  # Core Functions
119
+ # =============================
120
  def ingest_inputs(jd_text: str, resume_text: str):
121
  jd_clean = normalize_text(jd_text)
122
  resume_clean = normalize_text(resume_text)
 
127
  def generate_improvements(jd_clean: str, resume_clean: str):
128
  if not jd_clean or not resume_clean:
129
  return "Please provide both Job Description and Resume."
130
+ out = call_openai_with_fallback(SYS_BASE, prompt_resume_improvements(resume_clean, jd_clean))
131
+ if out:
132
+ return out
 
133
  # Mock fallback
134
  score, matched = keyword_match_score(resume_clean, jd_clean)
135
  return (
 
145
  def generate_cover_letter(jd_clean: str, resume_clean: str):
146
  if not jd_clean or not resume_clean:
147
  return "Please provide both Job Description and Resume."
148
+ out = call_openai_with_fallback(SYS_BASE, prompt_cover_letter(resume_clean, jd_clean))
149
+ if out:
150
+ return out
 
151
  return (
152
  "(Mock Cover Letter)\n"
153
  "Dear Hiring Manager,\n\n"
 
161
  def generate_mock_interview(jd_clean: str, resume_clean: str, style: str):
162
  if not jd_clean or not resume_clean:
163
  return "Please provide both Job Description and Resume."
164
+ out = call_openai_with_fallback(SYS_BASE, prompt_mock_interview(resume_clean, jd_clean, style))
165
+ if out:
166
+ return out
 
167
  return (
168
  f"(Mock {style} Interview)\n\n"
169
  "Q1: Tell me about a project relevant to this role.\n"
 
183
  "Tip: Reference 1–2 specifics from the JD."
184
  )
185
 
186
+ # =============================
187
  # Demo Defaults
188
+ # =============================
189
  DEMO_JD = "Responsibilities: Collaborate, improve processes, analyze metrics. Preferred: Python, SQL."
190
  DEMO_RESUME = "Experience: Assisted in process improvement; created reports. Skills: Python, SQL, Excel."
191
 
192
+ # =============================
193
  # UI
194
+ # =============================
195
  with gr.Blocks(title="CareerForge — Resume & Interview Coach") as demo:
196
  gr.Markdown("# CareerForge — Resume & Interview Coach")
197
  gr.Markdown(