Update app.py
Browse files
app.py
CHANGED
|
@@ -323,12 +323,14 @@ def get_job_matches(dream_job: str, top_n: int, skills_text: str):
|
|
| 323 |
emb_matches = find_job_matches(dream_job, expanded_desc, top_k=50)
|
| 324 |
user_skills = [_norm_skill_token(s) for s in skills_text.split(',') if _norm_skill_token(s)]
|
| 325 |
|
|
|
|
| 326 |
recommendations_table = pd.DataFrame()
|
| 327 |
recommendations_visible = False
|
| 328 |
|
| 329 |
if user_skills:
|
| 330 |
scored_df = score_jobs_by_skills(user_skills, emb_matches)
|
| 331 |
|
|
|
|
| 332 |
skill_sorted_df = scored_df.sort_values(by='Skill Match Score', ascending=False).head(5)
|
| 333 |
if not skill_sorted_df.empty:
|
| 334 |
recs = skill_sorted_df[['job_title', 'company', 'Skill Match Score', 'Final Score']].copy()
|
|
@@ -337,6 +339,7 @@ def get_job_matches(dream_job: str, top_n: int, skills_text: str):
|
|
| 337 |
recs['Overall Score'] = recs['Overall Score'].map('{:.2%}'.format)
|
| 338 |
recommendations_table = recs
|
| 339 |
recommendations_visible = True
|
|
|
|
| 340 |
|
| 341 |
display_df = scored_df.head(top_n)
|
| 342 |
status = f"Found and **re-ranked** results by your {len(user_skills)} skills. Displaying top {len(display_df)}."
|
|
@@ -357,6 +360,7 @@ def get_job_matches(dream_job: str, top_n: int, skills_text: str):
|
|
| 357 |
dropdown_options = [(f"{i+1}. {row['job_title']} - {row['company']}", row.name) for i, row in display_df.iterrows()]
|
| 358 |
dropdown_value = dropdown_options[0][1] if dropdown_options else None
|
| 359 |
|
|
|
|
| 360 |
return status, emb_matches, table_to_show, gr.Dropdown(choices=dropdown_options, value=dropdown_value, visible=True), gr.Accordion(visible=True), recommendations_table, gr.Accordion(visible=recommendations_visible)
|
| 361 |
|
| 362 |
def rerank_current_results(initial_matches_df, skills_text, top_n):
|
|
@@ -365,6 +369,7 @@ def rerank_current_results(initial_matches_df, skills_text, top_n):
|
|
| 365 |
initial_matches_df = pd.DataFrame(initial_matches_df)
|
| 366 |
user_skills = [_norm_skill_token(s) for s in skills_text.split(',') if _norm_skill_token(s)]
|
| 367 |
|
|
|
|
| 368 |
recommendations_table = pd.DataFrame()
|
| 369 |
recommendations_visible = False
|
| 370 |
|
|
@@ -379,6 +384,7 @@ def rerank_current_results(initial_matches_df, skills_text, top_n):
|
|
| 379 |
status = f"Results **re-ranked** based on your {len(user_skills)} skills."
|
| 380 |
display_df = ranked_df.head(top_n)
|
| 381 |
|
|
|
|
| 382 |
skill_sorted_df = ranked_df.sort_values(by='Skill Match Score', ascending=False).head(5)
|
| 383 |
if not skill_sorted_df.empty:
|
| 384 |
recs = skill_sorted_df[['job_title', 'company', 'Skill Match Score', 'Final Score']].copy()
|
|
@@ -387,6 +393,7 @@ def rerank_current_results(initial_matches_df, skills_text, top_n):
|
|
| 387 |
recs['Overall Score'] = recs['Overall Score'].map('{:.2%}'.format)
|
| 388 |
recommendations_table = recs
|
| 389 |
recommendations_visible = True
|
|
|
|
| 390 |
|
| 391 |
table_to_show = display_df[['job_title', 'company', 'Final Score', 'Skill Match Score']]
|
| 392 |
table_to_show = table_to_show.rename(columns={'Final Score': 'Overall Score'})
|
|
@@ -396,15 +403,18 @@ def rerank_current_results(initial_matches_df, skills_text, top_n):
|
|
| 396 |
dropdown_options = [(f"{i+1}. {row['job_title']} - {row['company']}", row.name) for i, row in display_df.iterrows()]
|
| 397 |
dropdown_value = dropdown_options[0][1] if dropdown_options else None
|
| 398 |
|
|
|
|
| 399 |
return status, table_to_show, gr.Dropdown(choices=dropdown_options, value=dropdown_value, visible=True), recommendations_table, gr.Accordion(visible=recommendations_visible)
|
| 400 |
|
| 401 |
def find_matches_and_rank_with_check(dream_job: str, top_n: int, skills_text: str):
|
| 402 |
if not dream_job:
|
|
|
|
| 403 |
return "Please describe your dream job first.", None, pd.DataFrame(), gr.Dropdown(visible=False), gr.Accordion(visible=False), gr.Markdown(""), gr.Row(visible=False), pd.DataFrame(), gr.Accordion(visible=False)
|
| 404 |
unrecognized_words = check_spelling_in_query(dream_job)
|
| 405 |
if unrecognized_words:
|
| 406 |
word_list_html = ", ".join([f"<b><span style='color: #F87171;'>{w}</span></b>" for w in unrecognized_words])
|
| 407 |
alert_message = f"<b><span style='color: #F87171;'>⚠️ Possible Spelling Error:</span></b> Unrecognized: {word_list_html}."
|
|
|
|
| 408 |
return "Status: Awaiting confirmation.", None, pd.DataFrame(), gr.Dropdown(visible=False), gr.Accordion(visible=False), gr.Markdown(alert_message, visible=True), gr.Row(visible=True), pd.DataFrame(), gr.Accordion(visible=False)
|
| 409 |
|
| 410 |
status, emb_matches, table_to_show, dropdown, details_accordion, recommendations_table, recommendations_accordion = get_job_matches(dream_job, top_n, skills_text)
|
|
@@ -475,6 +485,7 @@ def load_more_skills(full_skills_list, current_offset):
|
|
| 475 |
return learning_plan_html, new_offset, gr.Button(visible=should_button_be_visible)
|
| 476 |
|
| 477 |
def on_reset():
|
|
|
|
| 478 |
return ("", 3, "", pd.DataFrame(), None, gr.Dropdown(visible=False), gr.Accordion(visible=False), "Status: Ready.", "", "", "", "", gr.Markdown(visible=False), gr.Row(visible=False), [], 0, gr.Button(visible=False), pd.DataFrame(), gr.Accordion(visible=False))
|
| 479 |
|
| 480 |
print("Starting application initialization...")
|
|
@@ -505,6 +516,7 @@ with gr.Blocks(theme=gr.themes.Soft()) as ui:
|
|
| 505 |
|
| 506 |
df_output = gr.DataFrame(label="Job Matches (Sorted by Overall Relevance)", interactive=False)
|
| 507 |
|
|
|
|
| 508 |
with gr.Accordion("✨ Based on your current skills and career interest consider these jobs...", open=True, visible=False) as recommendations_accordion:
|
| 509 |
recommendations_df_output = gr.DataFrame(label="Top Skill Matches", interactive=False)
|
| 510 |
|
|
@@ -518,6 +530,7 @@ with gr.Blocks(theme=gr.themes.Soft()) as ui:
|
|
| 518 |
learning_plan_output = gr.HTML(label="Learning Plan")
|
| 519 |
load_more_btn = gr.Button("Load More Skills", visible=False)
|
| 520 |
|
|
|
|
| 521 |
search_btn.click(fn=find_matches_and_rank_with_check, inputs=[dream_text, topk_slider, skills_text], outputs=[status_text, initial_matches_state, df_output, job_selector, details_accordion, spelling_alert, spelling_row, recommendations_df_output, recommendations_accordion])
|
| 522 |
search_anyway_btn.click(fn=find_matches_and_rank_anyway, inputs=[dream_text, topk_slider, skills_text], outputs=[status_text, initial_matches_state, df_output, job_selector, details_accordion, spelling_alert, spelling_row, recommendations_df_output, recommendations_accordion])
|
| 523 |
retype_btn.click(lambda: ("Status: Ready for you to retype.", None, pd.DataFrame(), gr.Dropdown(visible=False), gr.Accordion(visible=False), gr.Markdown(visible=False), gr.Row(visible=False), pd.DataFrame(), gr.Accordion(visible=False)), outputs=[status_text, initial_matches_state, df_output, job_selector, details_accordion, spelling_alert, spelling_row, recommendations_df_output, recommendations_accordion])
|
|
|
|
| 323 |
emb_matches = find_job_matches(dream_job, expanded_desc, top_k=50)
|
| 324 |
user_skills = [_norm_skill_token(s) for s in skills_text.split(',') if _norm_skill_token(s)]
|
| 325 |
|
| 326 |
+
# --- NEW: Initialize variables for the recommendations section ---
|
| 327 |
recommendations_table = pd.DataFrame()
|
| 328 |
recommendations_visible = False
|
| 329 |
|
| 330 |
if user_skills:
|
| 331 |
scored_df = score_jobs_by_skills(user_skills, emb_matches)
|
| 332 |
|
| 333 |
+
# --- NEW: Logic to get top 5 jobs based purely on skill match score ---
|
| 334 |
skill_sorted_df = scored_df.sort_values(by='Skill Match Score', ascending=False).head(5)
|
| 335 |
if not skill_sorted_df.empty:
|
| 336 |
recs = skill_sorted_df[['job_title', 'company', 'Skill Match Score', 'Final Score']].copy()
|
|
|
|
| 339 |
recs['Overall Score'] = recs['Overall Score'].map('{:.2%}'.format)
|
| 340 |
recommendations_table = recs
|
| 341 |
recommendations_visible = True
|
| 342 |
+
# --- END NEW ---
|
| 343 |
|
| 344 |
display_df = scored_df.head(top_n)
|
| 345 |
status = f"Found and **re-ranked** results by your {len(user_skills)} skills. Displaying top {len(display_df)}."
|
|
|
|
| 360 |
dropdown_options = [(f"{i+1}. {row['job_title']} - {row['company']}", row.name) for i, row in display_df.iterrows()]
|
| 361 |
dropdown_value = dropdown_options[0][1] if dropdown_options else None
|
| 362 |
|
| 363 |
+
# --- MODIFIED: Added new outputs for recommendations ---
|
| 364 |
return status, emb_matches, table_to_show, gr.Dropdown(choices=dropdown_options, value=dropdown_value, visible=True), gr.Accordion(visible=True), recommendations_table, gr.Accordion(visible=recommendations_visible)
|
| 365 |
|
| 366 |
def rerank_current_results(initial_matches_df, skills_text, top_n):
|
|
|
|
| 369 |
initial_matches_df = pd.DataFrame(initial_matches_df)
|
| 370 |
user_skills = [_norm_skill_token(s) for s in skills_text.split(',') if _norm_skill_token(s)]
|
| 371 |
|
| 372 |
+
# --- NEW: Initialize variables for the recommendations section ---
|
| 373 |
recommendations_table = pd.DataFrame()
|
| 374 |
recommendations_visible = False
|
| 375 |
|
|
|
|
| 384 |
status = f"Results **re-ranked** based on your {len(user_skills)} skills."
|
| 385 |
display_df = ranked_df.head(top_n)
|
| 386 |
|
| 387 |
+
# --- NEW: Logic to get top 5 jobs based purely on skill match score ---
|
| 388 |
skill_sorted_df = ranked_df.sort_values(by='Skill Match Score', ascending=False).head(5)
|
| 389 |
if not skill_sorted_df.empty:
|
| 390 |
recs = skill_sorted_df[['job_title', 'company', 'Skill Match Score', 'Final Score']].copy()
|
|
|
|
| 393 |
recs['Overall Score'] = recs['Overall Score'].map('{:.2%}'.format)
|
| 394 |
recommendations_table = recs
|
| 395 |
recommendations_visible = True
|
| 396 |
+
# --- END NEW ---
|
| 397 |
|
| 398 |
table_to_show = display_df[['job_title', 'company', 'Final Score', 'Skill Match Score']]
|
| 399 |
table_to_show = table_to_show.rename(columns={'Final Score': 'Overall Score'})
|
|
|
|
| 403 |
dropdown_options = [(f"{i+1}. {row['job_title']} - {row['company']}", row.name) for i, row in display_df.iterrows()]
|
| 404 |
dropdown_value = dropdown_options[0][1] if dropdown_options else None
|
| 405 |
|
| 406 |
+
# --- MODIFIED: Added new outputs for recommendations ---
|
| 407 |
return status, table_to_show, gr.Dropdown(choices=dropdown_options, value=dropdown_value, visible=True), recommendations_table, gr.Accordion(visible=recommendations_visible)
|
| 408 |
|
| 409 |
def find_matches_and_rank_with_check(dream_job: str, top_n: int, skills_text: str):
|
| 410 |
if not dream_job:
|
| 411 |
+
# --- MODIFIED: Added new default outputs ---
|
| 412 |
return "Please describe your dream job first.", None, pd.DataFrame(), gr.Dropdown(visible=False), gr.Accordion(visible=False), gr.Markdown(""), gr.Row(visible=False), pd.DataFrame(), gr.Accordion(visible=False)
|
| 413 |
unrecognized_words = check_spelling_in_query(dream_job)
|
| 414 |
if unrecognized_words:
|
| 415 |
word_list_html = ", ".join([f"<b><span style='color: #F87171;'>{w}</span></b>" for w in unrecognized_words])
|
| 416 |
alert_message = f"<b><span style='color: #F87171;'>⚠️ Possible Spelling Error:</span></b> Unrecognized: {word_list_html}."
|
| 417 |
+
# --- MODIFIED: Added new default outputs ---
|
| 418 |
return "Status: Awaiting confirmation.", None, pd.DataFrame(), gr.Dropdown(visible=False), gr.Accordion(visible=False), gr.Markdown(alert_message, visible=True), gr.Row(visible=True), pd.DataFrame(), gr.Accordion(visible=False)
|
| 419 |
|
| 420 |
status, emb_matches, table_to_show, dropdown, details_accordion, recommendations_table, recommendations_accordion = get_job_matches(dream_job, top_n, skills_text)
|
|
|
|
| 485 |
return learning_plan_html, new_offset, gr.Button(visible=should_button_be_visible)
|
| 486 |
|
| 487 |
def on_reset():
|
| 488 |
+
# --- MODIFIED: Added new default outputs for reset ---
|
| 489 |
return ("", 3, "", pd.DataFrame(), None, gr.Dropdown(visible=False), gr.Accordion(visible=False), "Status: Ready.", "", "", "", "", gr.Markdown(visible=False), gr.Row(visible=False), [], 0, gr.Button(visible=False), pd.DataFrame(), gr.Accordion(visible=False))
|
| 490 |
|
| 491 |
print("Starting application initialization...")
|
|
|
|
| 516 |
|
| 517 |
df_output = gr.DataFrame(label="Job Matches (Sorted by Overall Relevance)", interactive=False)
|
| 518 |
|
| 519 |
+
# --- NEW: Added the recommendations section ---
|
| 520 |
with gr.Accordion("✨ Based on your current skills and career interest consider these jobs...", open=True, visible=False) as recommendations_accordion:
|
| 521 |
recommendations_df_output = gr.DataFrame(label="Top Skill Matches", interactive=False)
|
| 522 |
|
|
|
|
| 530 |
learning_plan_output = gr.HTML(label="Learning Plan")
|
| 531 |
load_more_btn = gr.Button("Load More Skills", visible=False)
|
| 532 |
|
| 533 |
+
# --- MODIFIED: Added new outputs to the click events ---
|
| 534 |
search_btn.click(fn=find_matches_and_rank_with_check, inputs=[dream_text, topk_slider, skills_text], outputs=[status_text, initial_matches_state, df_output, job_selector, details_accordion, spelling_alert, spelling_row, recommendations_df_output, recommendations_accordion])
|
| 535 |
search_anyway_btn.click(fn=find_matches_and_rank_anyway, inputs=[dream_text, topk_slider, skills_text], outputs=[status_text, initial_matches_state, df_output, job_selector, details_accordion, spelling_alert, spelling_row, recommendations_df_output, recommendations_accordion])
|
| 536 |
retype_btn.click(lambda: ("Status: Ready for you to retype.", None, pd.DataFrame(), gr.Dropdown(visible=False), gr.Accordion(visible=False), gr.Markdown(visible=False), gr.Row(visible=False), pd.DataFrame(), gr.Accordion(visible=False)), outputs=[status_text, initial_matches_state, df_output, job_selector, details_accordion, spelling_alert, spelling_row, recommendations_df_output, recommendations_accordion])
|