Spaces:
Running
Running
| from fastapi import FastAPI, HTTPException | |
| from fastapi.middleware.cors import CORSMiddleware | |
| from pydantic import BaseModel | |
| import requests | |
| import os # for reading environment variables | |
| app = FastAPI() | |
| # Enable CORS | |
| app.add_middleware( | |
| CORSMiddleware, | |
| allow_origins=["*"], # Allow all origins, or replace with your frontend URL | |
| allow_credentials=True, | |
| allow_methods=["*"], | |
| allow_headers=["*"], | |
| ) | |
| # Read OpenRouter API key from environment variable (HF Secret) | |
| OPENROUTER_API_KEY = os.environ.get("OPENROUTER_API_KEY") | |
| if not OPENROUTER_API_KEY: | |
| raise RuntimeError("OPENROUTER_API_KEY environment variable not set!") | |
| # Request schema | |
| class ExplainRequest(BaseModel): | |
| message: str | |
| label: str # "Phishing" or "Safe" | |
| def explain(req: ExplainRequest): | |
| user_message = req.message.strip() | |
| label = req.label.strip() | |
| if not user_message or not label: | |
| raise HTTPException(status_code=400, detail="Missing message or label") | |
| # Updated system prompt with bullet-point format and language adaptation | |
| system_prompt = ( | |
| f"You are a robot that identifies phishing and safe messages. " | |
| f"The message was classified as '{label}'. " | |
| "Explain why this decision was made and point out any words or patterns that led to it. " | |
| "No greetings, introductions, or closing remarks. " | |
| "Don't restate the message or its classification. " | |
| "Output only the explanation as bullet points. " | |
| "Limit each bullet to 1–2 sentences. " | |
| "Limit the number of bullets to 3-4 " | |
| f"Message:\n\n{user_message}" | |
| "Respond using the same language as the message." | |
| ) | |
| url = "https://openrouter.ai/api/v1/chat/completions" | |
| headers = { | |
| "Authorization": f"Bearer {OPENROUTER_API_KEY}", | |
| "Content-Type": "application/json" | |
| } | |
| payload = { | |
| "model": "arcee-ai/trinity-large-preview:free", | |
| "messages": [ | |
| {"role": "system", "content": system_prompt}, | |
| {"role": "user", "content": user_message} | |
| ] | |
| } | |
| try: | |
| response = requests.post(url, headers=headers, json=payload, timeout=20) | |
| response.raise_for_status() | |
| result = response.json() | |
| reply = result.get("choices", [{}])[0].get("message", {}).get("content", "").strip() | |
| if not reply: | |
| reply = "[No explanation returned]" | |
| return {"reply": reply} | |
| except requests.RequestException as e: | |
| raise HTTPException(status_code=500, detail=f"Error contacting OpenRouter: {e}") | |