Spaces:
Sleeping
Sleeping
| """ | |
| 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) | |