Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
|
|
| 1 |
import gradio as gr
|
| 2 |
from langchain_community.document_loaders.pdf import PyPDFLoader
|
| 3 |
from langchain_community.embeddings import HuggingFaceEmbeddings
|
|
@@ -11,24 +12,11 @@ from collections import Counter
|
|
| 11 |
import numpy as np
|
| 12 |
import tempfile
|
| 13 |
import os
|
| 14 |
-
import requests
|
| 15 |
-
from bs4 import BeautifulSoup
|
| 16 |
|
| 17 |
load_dotenv()
|
| 18 |
groq_api_key = os.getenv("GROQ_API_KEY")
|
| 19 |
os.environ["GROQ_API_KEY"] = groq_api_key
|
| 20 |
|
| 21 |
-
def scrape_skills_from_jd_link(url):
|
| 22 |
-
try:
|
| 23 |
-
response = requests.get(url, timeout=10)
|
| 24 |
-
soup = BeautifulSoup(response.text, 'html.parser')
|
| 25 |
-
text = soup.get_text(separator=' ', strip=True)
|
| 26 |
-
skills_list = ["Python", "SQL", "Machine Learning", "Deep Learning", "NLP", "Cloud", "TensorFlow", "Java", "C++", "HTML", "CSS", "JavaScript"]
|
| 27 |
-
extracted_skills = [skill for skill in skills_list if skill.lower() in text.lower()]
|
| 28 |
-
return extracted_skills if extracted_skills else ["No skills detected."]
|
| 29 |
-
except Exception as e:
|
| 30 |
-
return [f"Error fetching JD: {str(e)}"]
|
| 31 |
-
|
| 32 |
def extract_text_from_pdf(pdf_file):
|
| 33 |
with tempfile.NamedTemporaryFile(delete=False, suffix=".pdf") as temp:
|
| 34 |
temp.write(pdf_file)
|
|
@@ -102,14 +90,9 @@ def create_pdf(full_report_text):
|
|
| 102 |
pdf.output(output_path)
|
| 103 |
return output_path
|
| 104 |
|
| 105 |
-
def process_skill_gap(resume_pdf, jd_pdfs
|
| 106 |
if resume_pdf is None or jd_pdfs is None:
|
| 107 |
-
return "", "", "", "", "", None, "", "", ""
|
| 108 |
-
|
| 109 |
-
scraped_skills_text = ""
|
| 110 |
-
if jd_link_url:
|
| 111 |
-
scraped_skills = scrape_skills_from_jd_link(jd_link_url)
|
| 112 |
-
scraped_skills_text = ", ".join(scraped_skills)
|
| 113 |
|
| 114 |
resume_text = extract_text_from_pdf(resume_pdf)
|
| 115 |
user_skills = extract_skills(resume_text)
|
|
@@ -149,17 +132,11 @@ def process_skill_gap(resume_pdf, jd_pdfs, jd_link_url):
|
|
| 149 |
pdf_path = create_pdf(full_report_clean)
|
| 150 |
progress_display = generate_circular_progress(overall_match)
|
| 151 |
|
| 152 |
-
return progress_display, "β
Analysis done across all JDs", ", ".join(set(all_missing_skills)), "Multi-JD Comparison Completed", full_report, pdf_path, top_missing_skills_text, resources, certifications
|
| 153 |
|
| 154 |
with gr.Blocks() as demo:
|
| 155 |
-
gr.HTML("""<style>body{background: linear-gradient(135deg, #0d1b2a, #1b263b, #415a77);background-size: 300% 300%;animation: gradientShift 15s ease infinite;overflow-x: hidden;position: relative}@keyframes gradientShift{0%{background-position:0% 50%}50%{background-position:100% 50%}100%{background-position:0% 50%}.floating-circle{position:fixed;border-radius:50%;background:rgba(0,255,255,0.08);box-shadow:0 0 20px rgba(0,255,255,0.2);animation:floatUp linear infinite;z-index:-1;filter:blur(2px)}@keyframes floatUp{0%{transform:translateY(100vh);opacity:0}10%{opacity:.2}90%{opacity:.2}100%{transform:translateY(-200px);opacity:0}}.floating-circle:nth-child(1){width:80px;height:80px;left:20%;animation-duration:25s}.floating-circle:nth-child(2){width:100px;height:100px;left:50%;animation-duration:30s;animation-delay:5s}.floating-circle:nth-child(3){width:60px;height:60px;left:70%;animation-duration:20s;animation-delay:10s}.floating-circle:nth-child(4){width:90px;height:90px;left:35%;animation-duration:35s;animation-delay:15s}.floating-circle:nth-child(5){width:120px;height:120px;left:80%;animation-duration:40s;animation-delay:20s}h1,h2,h3,p,label{color:#00f7ff!important;text-shadow:0 0 8px rgba(0,255,255,0.3)}</style><div class='floating-circle'></div><div class='floating-circle'></div><div class='floating-circle'></div><div class='floating-circle'></div><div class='floating-circle'></div>""")
|
| 156 |
-
|
| 157 |
-
gr.Markdown("# π§ TALENTPATCH with Multi-JD Comparison and AI Skill Gap Analysis")
|
| 158 |
-
|
| 159 |
resume_file = gr.File(label="π Upload Resume (PDF)", type="binary")
|
| 160 |
jd_files = gr.File(label="π Upload Multiple Job Descriptions (PDFs)", type="binary", file_types=[".pdf"], file_count="multiple")
|
| 161 |
-
jd_link_input = gr.Textbox(label="π Optional: Paste JD URL for Real-Time Skill Extraction")
|
| 162 |
-
|
| 163 |
match_progress = gr.HTML(label="Skill Match Progress")
|
| 164 |
skill_match_text = gr.Textbox(label="Status", interactive=False)
|
| 165 |
missing_skills_text = gr.Textbox(label="All Missing Skills", interactive=False)
|
|
@@ -169,13 +146,10 @@ with gr.Blocks() as demo:
|
|
| 169 |
top_skills_output = gr.Textbox(label="Top Missing Skills Across JDs", interactive=False)
|
| 170 |
learning_resources = gr.Markdown(label="π AI Learning Resource Recommendations")
|
| 171 |
certification_output = gr.Textbox(label="π Recommended Certifications", interactive=False)
|
| 172 |
-
scraped_skills_output = gr.Textbox(label="π Skills Extracted from JD Link", interactive=False)
|
| 173 |
-
|
| 174 |
submit_btn = gr.Button("π Analyze Skill Gap")
|
| 175 |
-
|
| 176 |
submit_btn.click(
|
| 177 |
fn=process_skill_gap,
|
| 178 |
-
inputs=[resume_file, jd_files
|
| 179 |
outputs=[
|
| 180 |
match_progress,
|
| 181 |
skill_match_text,
|
|
@@ -185,9 +159,7 @@ with gr.Blocks() as demo:
|
|
| 185 |
download_pdf,
|
| 186 |
top_skills_output,
|
| 187 |
learning_resources,
|
| 188 |
-
certification_output
|
| 189 |
-
scraped_skills_output
|
| 190 |
]
|
| 191 |
)
|
| 192 |
-
|
| 193 |
-
demo.launch()
|
|
|
|
| 1 |
+
|
| 2 |
import gradio as gr
|
| 3 |
from langchain_community.document_loaders.pdf import PyPDFLoader
|
| 4 |
from langchain_community.embeddings import HuggingFaceEmbeddings
|
|
|
|
| 12 |
import numpy as np
|
| 13 |
import tempfile
|
| 14 |
import os
|
|
|
|
|
|
|
| 15 |
|
| 16 |
load_dotenv()
|
| 17 |
groq_api_key = os.getenv("GROQ_API_KEY")
|
| 18 |
os.environ["GROQ_API_KEY"] = groq_api_key
|
| 19 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 20 |
def extract_text_from_pdf(pdf_file):
|
| 21 |
with tempfile.NamedTemporaryFile(delete=False, suffix=".pdf") as temp:
|
| 22 |
temp.write(pdf_file)
|
|
|
|
| 90 |
pdf.output(output_path)
|
| 91 |
return output_path
|
| 92 |
|
| 93 |
+
def process_skill_gap(resume_pdf, jd_pdfs):
|
| 94 |
if resume_pdf is None or jd_pdfs is None:
|
| 95 |
+
return "", "", "", "", "", None, "", "", ""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 96 |
|
| 97 |
resume_text = extract_text_from_pdf(resume_pdf)
|
| 98 |
user_skills = extract_skills(resume_text)
|
|
|
|
| 132 |
pdf_path = create_pdf(full_report_clean)
|
| 133 |
progress_display = generate_circular_progress(overall_match)
|
| 134 |
|
| 135 |
+
return progress_display, "β
Analysis done across all JDs", ", ".join(set(all_missing_skills)), "Multi-JD Comparison Completed", full_report, pdf_path, top_missing_skills_text, resources, certifications
|
| 136 |
|
| 137 |
with gr.Blocks() as demo:
|
|
|
|
|
|
|
|
|
|
|
|
|
| 138 |
resume_file = gr.File(label="π Upload Resume (PDF)", type="binary")
|
| 139 |
jd_files = gr.File(label="π Upload Multiple Job Descriptions (PDFs)", type="binary", file_types=[".pdf"], file_count="multiple")
|
|
|
|
|
|
|
| 140 |
match_progress = gr.HTML(label="Skill Match Progress")
|
| 141 |
skill_match_text = gr.Textbox(label="Status", interactive=False)
|
| 142 |
missing_skills_text = gr.Textbox(label="All Missing Skills", interactive=False)
|
|
|
|
| 146 |
top_skills_output = gr.Textbox(label="Top Missing Skills Across JDs", interactive=False)
|
| 147 |
learning_resources = gr.Markdown(label="π AI Learning Resource Recommendations")
|
| 148 |
certification_output = gr.Textbox(label="π Recommended Certifications", interactive=False)
|
|
|
|
|
|
|
| 149 |
submit_btn = gr.Button("π Analyze Skill Gap")
|
|
|
|
| 150 |
submit_btn.click(
|
| 151 |
fn=process_skill_gap,
|
| 152 |
+
inputs=[resume_file, jd_files],
|
| 153 |
outputs=[
|
| 154 |
match_progress,
|
| 155 |
skill_match_text,
|
|
|
|
| 159 |
download_pdf,
|
| 160 |
top_skills_output,
|
| 161 |
learning_resources,
|
| 162 |
+
certification_output
|
|
|
|
| 163 |
]
|
| 164 |
)
|
| 165 |
+
demo.launch()
|
|
|