Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -1,47 +1,46 @@
|
|
1 |
import pandas as pd
|
2 |
import gradio as gr
|
3 |
-
|
4 |
-
from reranker import rerank
|
5 |
from fastapi import FastAPI, Request
|
6 |
from fastapi.responses import JSONResponse
|
7 |
-
from fastapi.middleware.cors import CORSMiddleware
|
8 |
from gradio.routes import mount_gradio_app
|
9 |
-
import json
|
10 |
|
11 |
-
|
12 |
-
|
13 |
|
14 |
-
#
|
15 |
-
app
|
16 |
-
CORSMiddleware,
|
17 |
-
allow_origins=["*"],
|
18 |
-
allow_credentials=True,
|
19 |
-
allow_methods=["*"],
|
20 |
-
allow_headers=["*"],
|
21 |
-
)
|
22 |
|
23 |
-
#
|
24 |
def clean_df(df):
|
25 |
df = df.copy()
|
26 |
second_col = df.iloc[:, 2].astype(str)
|
|
|
27 |
if second_col.str.contains('http').any() or second_col.str.contains('www').any():
|
28 |
df["url"] = second_col
|
29 |
else:
|
30 |
df["url"] = "https://www.shl.com" + second_col.str.replace(r'^(?!/)', '/', regex=True)
|
|
|
31 |
df["remote_support"] = df.iloc[:, 3].map(lambda x: "Yes" if x == "T" else "No")
|
32 |
df["adaptive_support"] = df.iloc[:, 4].map(lambda x: "Yes" if x == "T" else "No")
|
33 |
df["test_type"] = df.iloc[:, 5].apply(lambda x: eval(x) if isinstance(x, str) else x)
|
34 |
df["description"] = df.iloc[:, 6]
|
35 |
-
|
|
|
|
|
|
|
|
|
|
|
36 |
return df[["url", "adaptive_support", "remote_support", "description", "duration", "test_type"]]
|
37 |
|
38 |
try:
|
39 |
df = pd.read_csv("assesments.csv", encoding='utf-8')
|
40 |
df_clean = clean_df(df)
|
41 |
except Exception as e:
|
42 |
-
print(f"Error loading
|
43 |
df_clean = pd.DataFrame(columns=["url", "adaptive_support", "remote_support", "description", "duration", "test_type"])
|
44 |
|
|
|
45 |
def validate_and_fix_urls(candidates):
|
46 |
for candidate in candidates:
|
47 |
if not isinstance(candidate, dict):
|
@@ -57,6 +56,7 @@ def validate_and_fix_urls(candidates):
|
|
57 |
candidate['url'] = f"https://www.shl.com{url}" if url.startswith('/') else f"https://www.shl.com/{url}"
|
58 |
return candidates
|
59 |
|
|
|
60 |
def recommend(query):
|
61 |
if not query.strip():
|
62 |
return {"error": "Please enter a job description"}
|
@@ -65,8 +65,8 @@ def recommend(query):
|
|
65 |
if top_k_df.empty:
|
66 |
return {"error": "No matching assessments found"}
|
67 |
top_k_df['test_type'] = top_k_df['test_type'].apply(
|
68 |
-
lambda x: x if isinstance(x, list) else
|
69 |
-
|
70 |
)
|
71 |
top_k_df['duration'] = top_k_df['duration'].fillna(-1).astype(int)
|
72 |
top_k_df.loc[top_k_df['duration'] == -1, 'duration'] = None
|
@@ -78,17 +78,32 @@ def recommend(query):
|
|
78 |
return result
|
79 |
except Exception as e:
|
80 |
import traceback
|
81 |
-
|
|
|
82 |
|
83 |
-
# ---
|
84 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
85 |
async def health_check():
|
86 |
return JSONResponse(
|
87 |
status_code=200,
|
88 |
content={"status": "healthy"},
|
89 |
media_type="application/json"
|
90 |
)
|
91 |
-
|
|
|
|
|
92 |
async def recommend_api(request: Request):
|
93 |
body = await request.json()
|
94 |
query = body.get("query", "").strip()
|
@@ -104,7 +119,3 @@ async def recommend_api(request: Request):
|
|
104 |
content=result,
|
105 |
media_type="application/json"
|
106 |
)
|
107 |
-
# Mount Gradio app at root
|
108 |
-
app = mount_gradio_app(app, gradio_iface, path="/")
|
109 |
-
|
110 |
-
# Hugging Face Spaces runs `app` object, so no need for __main__
|
|
|
1 |
import pandas as pd
|
2 |
import gradio as gr
|
3 |
+
import json
|
|
|
4 |
from fastapi import FastAPI, Request
|
5 |
from fastapi.responses import JSONResponse
|
|
|
6 |
from gradio.routes import mount_gradio_app
|
|
|
7 |
|
8 |
+
from retriever import get_relevant_passages
|
9 |
+
from reranker import rerank
|
10 |
|
11 |
+
# FastAPI app instance
|
12 |
+
app = FastAPI()
|
|
|
|
|
|
|
|
|
|
|
|
|
13 |
|
14 |
+
# --- CSV Loading and Cleaning ---
|
15 |
def clean_df(df):
|
16 |
df = df.copy()
|
17 |
second_col = df.iloc[:, 2].astype(str)
|
18 |
+
|
19 |
if second_col.str.contains('http').any() or second_col.str.contains('www').any():
|
20 |
df["url"] = second_col
|
21 |
else:
|
22 |
df["url"] = "https://www.shl.com" + second_col.str.replace(r'^(?!/)', '/', regex=True)
|
23 |
+
|
24 |
df["remote_support"] = df.iloc[:, 3].map(lambda x: "Yes" if x == "T" else "No")
|
25 |
df["adaptive_support"] = df.iloc[:, 4].map(lambda x: "Yes" if x == "T" else "No")
|
26 |
df["test_type"] = df.iloc[:, 5].apply(lambda x: eval(x) if isinstance(x, str) else x)
|
27 |
df["description"] = df.iloc[:, 6]
|
28 |
+
|
29 |
+
df["duration"] = pd.to_numeric(
|
30 |
+
df.iloc[:, 9].astype(str).str.extract(r'(\d+)')[0],
|
31 |
+
errors='coerce'
|
32 |
+
)
|
33 |
+
|
34 |
return df[["url", "adaptive_support", "remote_support", "description", "duration", "test_type"]]
|
35 |
|
36 |
try:
|
37 |
df = pd.read_csv("assesments.csv", encoding='utf-8')
|
38 |
df_clean = clean_df(df)
|
39 |
except Exception as e:
|
40 |
+
print(f"Error loading data: {e}")
|
41 |
df_clean = pd.DataFrame(columns=["url", "adaptive_support", "remote_support", "description", "duration", "test_type"])
|
42 |
|
43 |
+
# --- Utility ---
|
44 |
def validate_and_fix_urls(candidates):
|
45 |
for candidate in candidates:
|
46 |
if not isinstance(candidate, dict):
|
|
|
56 |
candidate['url'] = f"https://www.shl.com{url}" if url.startswith('/') else f"https://www.shl.com/{url}"
|
57 |
return candidates
|
58 |
|
59 |
+
# --- Core Recommend Logic ---
|
60 |
def recommend(query):
|
61 |
if not query.strip():
|
62 |
return {"error": "Please enter a job description"}
|
|
|
65 |
if top_k_df.empty:
|
66 |
return {"error": "No matching assessments found"}
|
67 |
top_k_df['test_type'] = top_k_df['test_type'].apply(
|
68 |
+
lambda x: x if isinstance(x, list) else
|
69 |
+
(eval(x) if isinstance(x, str) and x.startswith('[') else [str(x)])
|
70 |
)
|
71 |
top_k_df['duration'] = top_k_df['duration'].fillna(-1).astype(int)
|
72 |
top_k_df.loc[top_k_df['duration'] == -1, 'duration'] = None
|
|
|
78 |
return result
|
79 |
except Exception as e:
|
80 |
import traceback
|
81 |
+
print(traceback.format_exc())
|
82 |
+
return {"error": f"Error processing request: {str(e)}"}
|
83 |
|
84 |
+
# --- Gradio Interface ---
|
85 |
+
iface = gr.Interface(
|
86 |
+
fn=recommend,
|
87 |
+
inputs=gr.Textbox(label="Enter Job Description", lines=4),
|
88 |
+
outputs="json",
|
89 |
+
title="SHL Assessment Recommender",
|
90 |
+
description="Paste a job description to get the most relevant SHL assessments."
|
91 |
+
)
|
92 |
+
|
93 |
+
# --- Mount Gradio at "/" ---
|
94 |
+
app = mount_gradio_app(app, iface, path="/")
|
95 |
+
|
96 |
+
# --- /health Endpoint ---
|
97 |
+
@app.get("/health", response_class=JSONResponse)
|
98 |
async def health_check():
|
99 |
return JSONResponse(
|
100 |
status_code=200,
|
101 |
content={"status": "healthy"},
|
102 |
media_type="application/json"
|
103 |
)
|
104 |
+
|
105 |
+
# --- /recommend Endpoint ---
|
106 |
+
@app.post("/recommend", response_class=JSONResponse)
|
107 |
async def recommend_api(request: Request):
|
108 |
body = await request.json()
|
109 |
query = body.get("query", "").strip()
|
|
|
119 |
content=result,
|
120 |
media_type="application/json"
|
121 |
)
|
|
|
|
|
|
|
|