import json import re import gradio as gr # ---------------------------- # Load Kent rubric titles # ---------------------------- with open("titles.json", "r", encoding="utf-8") as f: RAW_TITLES = json.load(f) def normalize(text: str) -> str: text = text.lower() text = re.sub(r"[^a-z0-9\s]", " ", text) text = re.sub(r"\s+", " ", text).strip() return text TITLES = [ { "original": title, "norm": normalize(title) } for title in RAW_TITLES ] # ---------------------------- # Search function # ---------------------------- def search(query, top_k=5): q = normalize(query) if not q: return [] scored = [] for item in TITLES: score = 0.0 # Strong signal: substring match if q in item["norm"]: score += 1.0 # Weaker signal: token overlap q_tokens = set(q.split()) t_tokens = set(item["norm"].split()) overlap = len(q_tokens & t_tokens) score += overlap * 0.1 if score > 0: scored.append((score, item["original"])) scored.sort(reverse=True) return [ { "rubric": title, "score": round(score, 3) } for score, title in scored[:int(top_k)] ] # ---------------------------- # Gradio interface (API host) # ---------------------------- api = gr.Interface( fn=search, inputs=[ gr.Textbox(label="query"), gr.Number(label="top_k", value=5) ], outputs="json", api_name="search" # 🔴 THIS IS THE KEY LINE ) if __name__ == "__main__": api.launch()