NU-KIOSK-API / backend /tools /faculty_by_topic.py
Monish BV
Add kiosk-api: stripped backend for speech integration
c2b7a7b
"""Blueprint identifying faculty whose research mentions a given topic."""
from __future__ import annotations
import re
from typing import Any, Dict, List
from .base import AnalysisContext, Blueprint, BlueprintResult, Fact
class FacultyByTopicBlueprint(Blueprint):
"""Return faculty whose research interests mention a topic."""
name = "faculty_by_topic"
def run(self, context: AnalysisContext, **kwargs: Any) -> BlueprintResult:
topic = (kwargs.get("topic") or "").strip()
if not topic:
return BlueprintResult(self.name, kwargs, facts=[], notes=["No topic provided."])
topic_lower = re.sub(r"[?.!]+$", "", topic.lower())
tokens = [tok for tok in re.split(r"[^a-z0-9]+", topic_lower) if tok]
if not tokens:
return BlueprintResult(self.name, kwargs, facts=[], notes=[f"Topic '{topic}' is too vague."])
search_terms = set()
search_terms.add(" ".join(tokens))
search_terms.update(tokens)
if "ai" in tokens:
search_terms.add("artificial intelligence")
if "ml" in tokens:
search_terms.add("machine learning")
dataset = context.catalog.get("faculty")
matches: List[Fact] = []
for row in dataset.records:
research = (row.get("Research Interests") or "").lower()
if any(term in research for term in search_terms):
matches.append(
Fact(
subject=row.get("Name", "Unknown"),
predicate="research_focus",
value=row.get("Research Interests"),
source=dataset.origin,
)
)
notes: List[str] = []
if not matches:
notes.append(f"No faculty rows mention '{topic}'.")
return BlueprintResult(self.name, kwargs, facts=matches, notes=notes)