Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -1,19 +1,42 @@
|
|
1 |
import gradio as gr
|
2 |
from keybert import KeyBERT
|
3 |
from sentence_transformers import SentenceTransformer
|
|
|
4 |
|
5 |
# β
Load Hugging Face model (no API key needed)
|
6 |
model = SentenceTransformer('all-MiniLM-L6-v2')
|
7 |
kw_model = KeyBERT(model)
|
8 |
|
9 |
-
# π
|
|
|
|
|
|
|
|
|
|
|
10 |
def extract_keywords(job_desc, resume_text, analyze_with_jd):
|
11 |
if not resume_text.strip():
|
12 |
-
return "Please paste your resume."
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
13 |
|
14 |
-
|
15 |
-
keywords = kw_model.extract_keywords(text, top_n=10, stop_words='english')
|
16 |
-
return ", ".join([kw for kw, _ in keywords]) if keywords else "No keywords found."
|
17 |
|
18 |
# ποΈ Gradio UI
|
19 |
with gr.Blocks() as demo:
|
@@ -23,7 +46,7 @@ with gr.Blocks() as demo:
|
|
23 |
job_desc = gr.Textbox(label="Job Description", lines=6, placeholder="Paste job description here...")
|
24 |
resume_text = gr.Textbox(label="Resume Text", lines=12, placeholder="Paste resume content here...")
|
25 |
with gr.Column():
|
26 |
-
output_keywords = gr.
|
27 |
|
28 |
resume_text.change(fn=extract_keywords, inputs=[job_desc, resume_text, analyze_checkbox], outputs=output_keywords)
|
29 |
job_desc.change(fn=extract_keywords, inputs=[job_desc, resume_text, analyze_checkbox], outputs=output_keywords)
|
|
|
1 |
import gradio as gr
|
2 |
from keybert import KeyBERT
|
3 |
from sentence_transformers import SentenceTransformer
|
4 |
+
import re
|
5 |
|
6 |
# β
Load Hugging Face model (no API key needed)
|
7 |
model = SentenceTransformer('all-MiniLM-L6-v2')
|
8 |
kw_model = KeyBERT(model)
|
9 |
|
10 |
+
# π Helper: Clean keywords from text (split on commas, newlines)
|
11 |
+
def clean_keywords(text):
|
12 |
+
keywords = re.split(r"[,\n]", text.lower())
|
13 |
+
return set(kw.strip() for kw in keywords if kw.strip())
|
14 |
+
|
15 |
+
# π Main function
|
16 |
def extract_keywords(job_desc, resume_text, analyze_with_jd):
|
17 |
if not resume_text.strip():
|
18 |
+
return "β οΈ Please paste your resume text."
|
19 |
+
|
20 |
+
# Step 1: Combine input for keyword extraction
|
21 |
+
combined_text = job_desc + "\n\n" + resume_text if analyze_with_jd and job_desc else resume_text
|
22 |
+
extracted_keywords = kw_model.extract_keywords(combined_text, top_n=15, stop_words='english')
|
23 |
+
extracted_set = set([kw.lower() for kw, _ in extracted_keywords])
|
24 |
+
|
25 |
+
# Step 2: Tokenize job description and resume separately
|
26 |
+
jd_tokens = clean_keywords(job_desc) if analyze_with_jd and job_desc else set()
|
27 |
+
resume_tokens = clean_keywords(resume_text)
|
28 |
+
|
29 |
+
# Step 3: Match and miss
|
30 |
+
matched = sorted(jd_tokens & resume_tokens)
|
31 |
+
missing = sorted(jd_tokens - resume_tokens)
|
32 |
+
|
33 |
+
# Step 4: Output
|
34 |
+
result = ""
|
35 |
+
result += f"π **Extracted Keywords:** {', '.join(extracted_set)}\n\n"
|
36 |
+
result += f"β
**Matched (Job & Resume):** {', '.join(matched) or 'None'}\n"
|
37 |
+
result += f"β **Missing in Resume:** {', '.join(missing) or 'None'}\n"
|
38 |
|
39 |
+
return result
|
|
|
|
|
40 |
|
41 |
# ποΈ Gradio UI
|
42 |
with gr.Blocks() as demo:
|
|
|
46 |
job_desc = gr.Textbox(label="Job Description", lines=6, placeholder="Paste job description here...")
|
47 |
resume_text = gr.Textbox(label="Resume Text", lines=12, placeholder="Paste resume content here...")
|
48 |
with gr.Column():
|
49 |
+
output_keywords = gr.Markdown(label="Keyword Match Result") # Markdown for styled output
|
50 |
|
51 |
resume_text.change(fn=extract_keywords, inputs=[job_desc, resume_text, analyze_checkbox], outputs=output_keywords)
|
52 |
job_desc.change(fn=extract_keywords, inputs=[job_desc, resume_text, analyze_checkbox], outputs=output_keywords)
|