adAstra144 commited on
Commit
71fc0be
·
verified ·
1 Parent(s): e96a058

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +88 -5
app.py CHANGED
@@ -2,7 +2,12 @@ from fastapi import FastAPI, HTTPException
2
  from fastapi.middleware.cors import CORSMiddleware
3
  from pydantic import BaseModel
4
  import requests
5
- import os # for reading environment variables
 
 
 
 
 
6
 
7
  app = FastAPI()
8
 
@@ -23,12 +28,34 @@ if not OPENROUTER_API_KEY:
23
  # Request schema
24
  class ExplainRequest(BaseModel):
25
  message: str
26
- label: str # "Phishing" or "Safe"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
 
28
  @app.post("/explain")
29
  def explain(req: ExplainRequest):
 
30
  user_message = req.message.strip()
31
- label = req.label.strip()
32
 
33
  if not user_message or not label:
34
  raise HTTPException(status_code=400, detail="Missing message or label")
@@ -42,8 +69,8 @@ def explain(req: ExplainRequest):
42
  "Don't restate the message or its classification. "
43
  "Output only the explanation as bullet points. "
44
  "Limit each bullet to 1–2 sentences. "
45
- "Limit the number of bullets to 3-4 "
46
- f"Message:\n\n{user_message}"
47
  "Respond using the same language as the message."
48
  )
49
 
@@ -61,12 +88,68 @@ def explain(req: ExplainRequest):
61
  }
62
 
63
  try:
 
64
  response = requests.post(url, headers=headers, json=payload, timeout=20)
65
  response.raise_for_status()
66
  result = response.json()
67
  reply = result.get("choices", [{}])[0].get("message", {}).get("content", "").strip()
68
  if not reply:
69
  reply = "[No explanation returned]"
 
70
  return {"reply": reply}
71
  except requests.RequestException as e:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72
  raise HTTPException(status_code=500, detail=f"Error contacting OpenRouter: {e}")
 
 
 
 
 
 
2
  from fastapi.middleware.cors import CORSMiddleware
3
  from pydantic import BaseModel
4
  import requests
5
+ import os
6
+ import logging
7
+
8
+ # Configure logging
9
+ logging.basicConfig(level=logging.INFO)
10
+ logger = logging.getLogger(__name__)
11
 
12
  app = FastAPI()
13
 
 
28
  # Request schema
29
  class ExplainRequest(BaseModel):
30
  message: str
31
+ label: str = None # Optional, for explanations
32
+ model_id: str = "arcee-ai/trinity-large-preview:free" # Default model, can be overridden
33
+
34
+ @app.get("/")
35
+ def root():
36
+ return {
37
+ "status": "healthy",
38
+ "service": "Anti-Phishing Explainer",
39
+ "endpoints": {
40
+ "/explain": "POST - Generate explanation for classification",
41
+ "/classify": "POST - Classify text as Phishing or Safe",
42
+ "/health": "GET - Health check"
43
+ }
44
+ }
45
+
46
+ @app.get("/health")
47
+ def health():
48
+ return {
49
+ "status": "healthy",
50
+ "service": "explainer",
51
+ "openrouter_configured": bool(OPENROUTER_API_KEY)
52
+ }
53
 
54
  @app.post("/explain")
55
  def explain(req: ExplainRequest):
56
+ """Generate a human-readable explanation for why a message was classified as Phishing or Safe"""
57
  user_message = req.message.strip()
58
+ label = req.label.strip() if req.label else None
59
 
60
  if not user_message or not label:
61
  raise HTTPException(status_code=400, detail="Missing message or label")
 
69
  "Don't restate the message or its classification. "
70
  "Output only the explanation as bullet points. "
71
  "Limit each bullet to 1–2 sentences. "
72
+ "Limit the number of bullets to 3-4. "
73
+ f"Message:\n\n{user_message}\n\n"
74
  "Respond using the same language as the message."
75
  )
76
 
 
88
  }
89
 
90
  try:
91
+ logger.info(f"Calling OpenRouter /explain with model: arcee-ai/trinity-large-preview:free")
92
  response = requests.post(url, headers=headers, json=payload, timeout=20)
93
  response.raise_for_status()
94
  result = response.json()
95
  reply = result.get("choices", [{}])[0].get("message", {}).get("content", "").strip()
96
  if not reply:
97
  reply = "[No explanation returned]"
98
+ logger.info("Explanation generated successfully")
99
  return {"reply": reply}
100
  except requests.RequestException as e:
101
+ logger.error(f"OpenRouter error in /explain: {e}")
102
+ raise HTTPException(status_code=500, detail=f"Error contacting OpenRouter: {e}")
103
+
104
+ @app.post("/classify")
105
+ def classify(req: ExplainRequest):
106
+ """Classify text as Phishing or Safe via OpenRouter"""
107
+ user_message = req.message.strip()
108
+ if not user_message:
109
+ raise HTTPException(status_code=400, detail="Missing message")
110
+
111
+ # Use provided model_id or default
112
+ model_id = req.model_id or "arcee-ai/trinity-large-preview:free"
113
+
114
+ system_prompt = (
115
+ 'You are a phishing detector. Classify the text as "Phishing" or "Safe". '
116
+ 'Respond ONLY with valid JSON: {"label": "Phishing"|"Safe", "confidence": <0-100 float>}. '
117
+ 'No other text.'
118
+ )
119
+
120
+ url = "https://openrouter.ai/api/v1/chat/completions"
121
+ headers = {
122
+ "Authorization": f"Bearer {OPENROUTER_API_KEY}",
123
+ "Content-Type": "application/json"
124
+ }
125
+ payload = {
126
+ "model": model_id, # Use the passed model_id
127
+ "messages": [
128
+ {"role": "system", "content": system_prompt},
129
+ {"role": "user", "content": user_message}
130
+ ],
131
+ "temperature": 0.0,
132
+ "max_tokens": 256
133
+ }
134
+
135
+ try:
136
+ logger.info(f"Calling OpenRouter /classify with model: {model_id}")
137
+ response = requests.post(url, headers=headers, json=payload, timeout=20)
138
+ response.raise_for_status()
139
+ result = response.json()
140
+ reply = result.get("choices", [{}])[0].get("message", {}).get("content", "").strip()
141
+
142
+ if not reply:
143
+ logger.error("OpenRouter returned empty response")
144
+ raise HTTPException(status_code=500, detail="No response from OpenRouter")
145
+
146
+ logger.info(f"Classification successful with model {model_id}: {reply}")
147
+ return {"reply": reply, "status": response.status_code, "model": model_id}
148
+ except requests.RequestException as e:
149
+ logger.error(f"OpenRouter error in /classify: {e}")
150
  raise HTTPException(status_code=500, detail=f"Error contacting OpenRouter: {e}")
151
+
152
+ # Optional: Run with uvicorn
153
+ if __name__ == "__main__":
154
+ import uvicorn
155
+ uvicorn.run(app, host="0.0.0.0", port=7860)