Update app.py
Browse files
app.py
CHANGED
|
@@ -163,11 +163,7 @@ def initialize_data_and_model():
|
|
| 163 |
|
| 164 |
def extract_skills_llm(text: str) -> list[str]:
|
| 165 |
if not isinstance(text, str) or len(text.strip()) < 20 or not LLM_PIPELINE: return []
|
| 166 |
-
prompt = f"""
|
| 167 |
-
Instruct: You are an expert technical recruiter. Extract the key skills from the job description text. List technical and soft skills as a comma-separated string.
|
| 168 |
-
[Example 1] Text: "Requires 3+ years of experience in cloud infrastructure. Must be proficient in AWS, particularly EC2 and S3. Experience with Terraform for IaC is a plus." Extracted Skills: cloud infrastructure, aws, ec2, s3, terraform, infrastructure as code
|
| 169 |
-
[Example 2] Text: "Seeking a team lead with strong project management abilities. Must communicate effectively with stakeholders and manage timelines using Agile methodologies like Scrum." Extracted Skills: project management, leadership, stakeholder communication, agile, scrum
|
| 170 |
-
[Actual Task] Text: "{text}" Extracted Skills:"""
|
| 171 |
try:
|
| 172 |
response = LLM_PIPELINE(prompt, max_new_tokens=150, do_sample=False, temperature=0.1, return_full_text=False)
|
| 173 |
skills_text = response[0]['generated_text'].strip()
|
|
@@ -202,7 +198,7 @@ Instruct: You are an expert technical recruiter. Extract the key skills from the
|
|
| 202 |
def expand_skills_with_llm(job_title: str, existing_skills: list) -> list:
|
| 203 |
if not LLM_PIPELINE or not job_title or not existing_skills: return []
|
| 204 |
skills_to_add = 6 - len(existing_skills)
|
| 205 |
-
prompt = f"""Instruct: A job has the title "{job_title}"
|
| 206 |
try:
|
| 207 |
response = LLM_PIPELINE(prompt, max_new_tokens=50, do_sample=True, temperature=0.5, return_full_text=False)
|
| 208 |
new_skills_text = response[0]['generated_text'].strip()
|
|
@@ -279,7 +275,6 @@ def get_job_matches(dream_job: str, top_n: int):
|
|
| 279 |
def analyze_skills(dream_job, initial_matches_df, skills_text, top_n):
|
| 280 |
user_skills = [_norm_skill_token(s) for s in skills_text.split(',') if _norm_skill_token(s)]
|
| 281 |
if not user_skills:
|
| 282 |
-
# If skills are cleared, just show the original table without skill scores and hide the second table
|
| 283 |
table1_df = pd.DataFrame(initial_matches_df).head(top_n)
|
| 284 |
table1_to_show = table1_df[['job_title', 'company', 'Similarity Score']]
|
| 285 |
table1_to_show['Similarity Score'] = table1_to_show['Similarity Score'].map('{:.2%}'.format)
|
|
@@ -287,27 +282,27 @@ def analyze_skills(dream_job, initial_matches_df, skills_text, top_n):
|
|
| 287 |
|
| 288 |
status = "Analyzing skills and finding new job matches..."
|
| 289 |
|
| 290 |
-
# --- 1
|
| 291 |
-
|
| 292 |
-
|
| 293 |
-
|
| 294 |
|
| 295 |
-
|
| 296 |
-
|
| 297 |
-
|
| 298 |
|
| 299 |
-
# ---
|
| 300 |
combined_query = dream_job + ". My current skills are: " + skills_text
|
| 301 |
-
|
| 302 |
-
|
| 303 |
-
new_matches_df['Skill Match Score'] = new_matches_df['Skills'].apply(lambda job_skills: calculate_skill_match_score(user_skills, job_skills))
|
| 304 |
|
| 305 |
-
|
| 306 |
-
|
| 307 |
-
|
| 308 |
|
| 309 |
status = f"Re-ranked initial jobs and found new jobs for your skills."
|
| 310 |
-
|
|
|
|
| 311 |
|
| 312 |
def find_matches_and_rank_with_check(dream_job: str, top_n: int):
|
| 313 |
if not dream_job:
|
|
@@ -320,7 +315,6 @@ def find_matches_and_rank_with_check(dream_job: str, top_n: int):
|
|
| 320 |
return "Status: Awaiting confirmation.", None, pd.DataFrame(), gr.update(visible=False), gr.update(visible=False), gr.update(value=alert_message, visible=True), gr.update(visible=True), pd.DataFrame(), gr.update(visible=False)
|
| 321 |
|
| 322 |
status, emb_matches, table_to_show, dropdown_update, accordion_update = get_job_matches(dream_job, top_n)
|
| 323 |
-
# Hide the second table on a new search
|
| 324 |
return status, emb_matches, table_to_show, dropdown_update, accordion_update, gr.update(visible=False), gr.update(visible=False), pd.DataFrame(), gr.update(visible=False)
|
| 325 |
|
| 326 |
def find_matches_and_rank_anyway(dream_job: str, top_n: int):
|
|
|
|
| 163 |
|
| 164 |
def extract_skills_llm(text: str) -> list[str]:
|
| 165 |
if not isinstance(text, str) or len(text.strip()) < 20 or not LLM_PIPELINE: return []
|
| 166 |
+
prompt = f"""Instruct: You are an expert technical recruiter... [omitted for brevity]"""
|
|
|
|
|
|
|
|
|
|
|
|
|
| 167 |
try:
|
| 168 |
response = LLM_PIPELINE(prompt, max_new_tokens=150, do_sample=False, temperature=0.1, return_full_text=False)
|
| 169 |
skills_text = response[0]['generated_text'].strip()
|
|
|
|
| 198 |
def expand_skills_with_llm(job_title: str, existing_skills: list) -> list:
|
| 199 |
if not LLM_PIPELINE or not job_title or not existing_skills: return []
|
| 200 |
skills_to_add = 6 - len(existing_skills)
|
| 201 |
+
prompt = f"""Instruct: A job has the title "{job_title}"... [omitted for brevity]"""
|
| 202 |
try:
|
| 203 |
response = LLM_PIPELINE(prompt, max_new_tokens=50, do_sample=True, temperature=0.5, return_full_text=False)
|
| 204 |
new_skills_text = response[0]['generated_text'].strip()
|
|
|
|
| 275 |
def analyze_skills(dream_job, initial_matches_df, skills_text, top_n):
|
| 276 |
user_skills = [_norm_skill_token(s) for s in skills_text.split(',') if _norm_skill_token(s)]
|
| 277 |
if not user_skills:
|
|
|
|
| 278 |
table1_df = pd.DataFrame(initial_matches_df).head(top_n)
|
| 279 |
table1_to_show = table1_df[['job_title', 'company', 'Similarity Score']]
|
| 280 |
table1_to_show['Similarity Score'] = table1_to_show['Similarity Score'].map('{:.2%}'.format)
|
|
|
|
| 282 |
|
| 283 |
status = "Analyzing skills and finding new job matches..."
|
| 284 |
|
| 285 |
+
# --- LOGIC FOR TABLE 1 (Reranked Initial Jobs) ---
|
| 286 |
+
reranked_initial_jobs = pd.DataFrame(initial_matches_df)
|
| 287 |
+
reranked_initial_jobs['Skill Match Score'] = reranked_initial_jobs['Skills'].apply(lambda js: calculate_skill_match_score(user_skills, js))
|
| 288 |
+
reranked_initial_jobs = reranked_initial_jobs.sort_values(by='Skill Match Score', ascending=False)
|
| 289 |
|
| 290 |
+
table1_df = reranked_initial_jobs.head(top_n)[['job_title', 'company', 'Similarity Score', 'Skill Match Score']]
|
| 291 |
+
table1_df['Similarity Score'] = table1_df['Similarity Score'].map('{:.2%}'.format)
|
| 292 |
+
table1_df['Skill Match Score'] = table1_df['Skill Match Score'].map('{:.2%}'.format)
|
| 293 |
|
| 294 |
+
# --- LOGIC FOR TABLE 2 (New Skill-Based Jobs) ---
|
| 295 |
combined_query = dream_job + ". My current skills are: " + skills_text
|
| 296 |
+
newly_found_jobs = find_job_matches(combined_query, top_k=top_n)
|
| 297 |
+
newly_found_jobs['Skill Match Score'] = newly_found_jobs['Skills'].apply(lambda js: calculate_skill_match_score(user_skills, js))
|
|
|
|
| 298 |
|
| 299 |
+
table2_df = newly_found_jobs[['job_title', 'company', 'Similarity Score', 'Skill Match Score']]
|
| 300 |
+
table2_df['Similarity Score'] = table2_df['Similarity Score'].map('{:.2%}'.format)
|
| 301 |
+
table2_df['Skill Match Score'] = table2_df['Skill Match Score'].map('{:.2%}'.format)
|
| 302 |
|
| 303 |
status = f"Re-ranked initial jobs and found new jobs for your skills."
|
| 304 |
+
# Return in the correct order for the UI components
|
| 305 |
+
return status, table1_df, table2_df, gr.update(visible=True)
|
| 306 |
|
| 307 |
def find_matches_and_rank_with_check(dream_job: str, top_n: int):
|
| 308 |
if not dream_job:
|
|
|
|
| 315 |
return "Status: Awaiting confirmation.", None, pd.DataFrame(), gr.update(visible=False), gr.update(visible=False), gr.update(value=alert_message, visible=True), gr.update(visible=True), pd.DataFrame(), gr.update(visible=False)
|
| 316 |
|
| 317 |
status, emb_matches, table_to_show, dropdown_update, accordion_update = get_job_matches(dream_job, top_n)
|
|
|
|
| 318 |
return status, emb_matches, table_to_show, dropdown_update, accordion_update, gr.update(visible=False), gr.update(visible=False), pd.DataFrame(), gr.update(visible=False)
|
| 319 |
|
| 320 |
def find_matches_and_rank_anyway(dream_job: str, top_n: int):
|