SHL_Reco_sys / app.py
Saalil's picture
Upload 13 files
1567477 verified
Raw
History Blame Contribute Delete
8.92 kB
"""
Hugging Face Spaces deployment - Combined API and UI
"""
import os
os.environ['PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION'] = 'python'
import gradio as gr
import sys
import pandas as pd
from io import StringIO
# Add src to path for imports
from recommendation_engine import RecommendationEngine
import json
# Initialize engine
print("Loading recommendation engine...")
engine = RecommendationEngine(catalog_path='shl_catalogue.csv')
print("Engine loaded!")
def get_recommendations(query, top_k=10):
"""Get recommendations for a query"""
try:
if not query or len(query.strip()) < 10:
return "❌ Query must be at least 10 characters long."
# Get recommendations
result = engine.recommend(query, top_k=int(top_k))
# Format output
output = f"## 🎯 Top {top_k} Recommendations\n\n"
output += f"**Query:** {result['query']}\n\n"
# Table header
output += "| # | Assessment Name | Type | Score |\n"
output += "|---|----------------|------|-------|\n"
# Recommendations
for i, rec in enumerate(result['recommendations'], 1):
name = rec['assessment_name']
test_type = rec['test_type_label']
score = f"{rec['similarity_score']:.3f}"
output += f"| {i} | [{name}]({rec['url']}) | {test_type} | {score} |\n"
# LLM Explanation
if result.get('explanation'):
output += f"\n### πŸ’‘ AI Analysis\n\n{result['explanation']}\n"
# Best recommendation
if result.get('best_recommendation'):
output += f"\n**πŸ† Best Match:** {result['best_recommendation']}\n"
return output
except Exception as e:
return f"❌ Error: {str(e)}"
def get_recommendations_with_csv(query, top_k=10):
"""Get recommendations and return both markdown and CSV file"""
try:
if not query or len(query.strip()) < 10:
return "❌ Query must be at least 10 characters long.", None
# Get recommendations
result = engine.recommend(query, top_k=int(top_k))
# Format markdown output
output = f"## 🎯 Top {top_k} Recommendations\n\n"
output += f"**Query:** {result['query']}\n\n"
# Table header
output += "| # | Assessment Name | Type | Score |\n"
output += "|---|----------------|------|-------|\n"
# Recommendations
for i, rec in enumerate(result['recommendations'], 1):
name = rec['assessment_name']
test_type = rec['test_type_label']
score = f"{rec['similarity_score']:.3f}"
output += f"| {i} | [{name}]({rec['url']}) | {test_type} | {score} |\n"
# LLM Explanation
if result.get('explanation'):
output += f"\n### πŸ’‘ AI Analysis\n\n{result['explanation']}\n"
# Best recommendation
if result.get('best_recommendation'):
output += f"\n**πŸ† Best Match:** {result['best_recommendation']}\n"
# Create CSV file
csv_data = []
for i, rec in enumerate(result['recommendations'], 1):
csv_data.append({
'Rank': i,
'Query': result['query'],
'Assessment_Name': rec['assessment_name'],
'Assessment_URL': rec['url'],
'Test_Type': rec['test_type_label'],
'Relevance_Score': round(rec['similarity_score'], 4)
})
df = pd.DataFrame(csv_data)
csv_file = "recommendations.csv"
df.to_csv(csv_file, index=False)
return output, csv_file
except Exception as e:
return f"❌ Error: {str(e)}", None
def get_recommendations_json(query, top_k=10):
"""API endpoint - returns JSON"""
try:
if not query or len(query.strip()) < 10:
return {"error": "Query must be at least 10 characters long."}
result = engine.recommend(query, top_k=int(top_k))
# Format as per API specification
return {
"query": result['query'],
"recommendations": [
{
"assessment_name": rec['assessment_name'],
"url": rec['url'],
"relevance_score": rec['similarity_score'],
"test_type": rec['test_type_label']
}
for rec in result['recommendations']
],
"total_results": result['total_results'],
"explanation": result.get('explanation'),
"best_recommendation": result.get('best_recommendation')
}
except Exception as e:
return {"error": str(e)}
# Create Gradio interface with tabs
with gr.Blocks(title="SHL Assessment Recommendation System", theme=gr.themes.Soft()) as demo:
gr.Markdown("""
# 🎯 SHL Assessment Recommendation System
Intelligent AI-powered recommendation system for SHL assessments using RAG (Retrieval-Augmented Generation).
**Features:**
- πŸ” Semantic search with sentence embeddings
- πŸ€– AI explanations powered by Google Gemini
- βš–οΈ Smart balancing of technical & behavioral assessments
- πŸ“Š 54 assessments from SHL catalog
- πŸ“₯ Download recommendations as CSV
""")
with gr.Tabs():
# Tab 1: Web UI
with gr.Tab("🌐 Web Interface"):
gr.Markdown("### Enter your job description or query:")
with gr.Row():
with gr.Column(scale=4):
query_input = gr.Textbox(
label="Job Query",
placeholder="e.g., 'Java developer with collaboration skills'",
lines=3
)
with gr.Column(scale=1):
top_k_slider = gr.Slider(
minimum=1,
maximum=10,
value=10,
step=1,
label="Number of Recommendations"
)
recommend_btn = gr.Button("🎯 Get Recommendations", variant="primary", size="lg")
with gr.Row():
with gr.Column(scale=3):
output_md = gr.Markdown()
with gr.Column(scale=1):
csv_download = gr.File(label="πŸ“₯ Download CSV", visible=True)
recommend_btn.click(
fn=get_recommendations_with_csv,
inputs=[query_input, top_k_slider],
outputs=[output_md, csv_download]
)
gr.Examples(
examples=[
["I am hiring for Java developers who can also collaborate effectively with my business teams.", 10],
["Looking to hire mid-level professionals who are proficient in Python, SQL and JavaScript.", 10],
["I am hiring for an analyst and want to screen using Cognitive and personality tests.", 8],
["Entry-level sales professional needed for my team.", 5],
],
inputs=[query_input, top_k_slider],
)
# Tab 2: API
with gr.Tab("πŸ”Œ API"):
gr.Markdown("""
### REST API Endpoint
Use this interface to test the API JSON response format.
**Endpoint:** `/recommend` (POST)
**Request Format:**
```json
{
"query": "Your job description here",
"top_k": 10
}
```
""")
with gr.Row():
with gr.Column():
api_query_input = gr.Textbox(
label="Query",
placeholder="Enter job description",
lines=3
)
api_top_k = gr.Number(label="top_k", value=10, precision=0)
api_btn = gr.Button("πŸ“‘ Send API Request", variant="primary")
with gr.Column():
api_output = gr.JSON(label="API Response")
api_btn.click(
fn=get_recommendations_json,
inputs=[api_query_input, api_top_k],
outputs=api_output
)
# Launch
if __name__ == "__main__":
demo.launch(server_name="0.0.0.0", server_port=7860)