Spaces:
Sleeping
Sleeping
| from fastapi import FastAPI | |
| from pydantic import BaseModel | |
| from semantic_engine.pipeline import process_experience as process_raw_text | |
| from grievance_engine.preprocess import preprocess | |
| from grievance_engine.offensiveness import classify_text | |
| from grievance_engine.shap_explain import get_shap_values | |
| from grievance_engine.lexicon import get_lexicon_highlights | |
| from grievance_engine.evolving_lexicon import update_lexicon_if_needed | |
| app = FastAPI() | |
| # βββ Existing Experience Hub endpoint βββββββββββββββββββββββββββββββββββββββ | |
| class Request(BaseModel): | |
| text: str | |
| def analyze(req: Request): | |
| return process_raw_text(req.text) | |
| # βββ Grievance Module endpoint βββββββββββββββββββββββββββββββββββββββββββββββ | |
| class GrievanceRequest(BaseModel): | |
| text: str | |
| def analyze_grievance(req: GrievanceRequest): | |
| """ | |
| Analyze a student complaint for offensive/hate language. | |
| Returns classification label + SHAP token explanations + lexicon hits. | |
| """ | |
| cleaned = preprocess(req.text) | |
| analysis = classify_text(cleaned) | |
| shap_tokens = get_shap_values(cleaned) | |
| lexicon_hits = get_lexicon_highlights(cleaned) | |
| # βββ Hybrid Logic: Lexicon Override ββββββββββββββββββββββββββββββββββββββ | |
| # If the AI says 'neutral' but we found words in our hand-picked lexicon, | |
| # we upgrade it to 'offensive' to ensure campus-level safety. | |
| final_label = analysis["label"] | |
| if final_label == "neutral" and len(lexicon_hits) > 0: | |
| final_label = "offensive" | |
| # Evolving lexicon β learns from flagged complaints over time | |
| update_lexicon_if_needed(shap_tokens, final_label) | |
| return { | |
| "label": final_label, # "hate" | "offensive" | "neutral" | |
| "score": analysis["score"], # confidence 0β1 | |
| "all_scores": analysis["all_scores"], # original AI probabilities | |
| "shap_tokens": shap_tokens, # [{token, shap_score}] | |
| "lexicon_hits": lexicon_hits, # [{word, start, end}] | |
| "ai_label": analysis["label"] # show what the AI thought raw | |
| } | |