Socrates_docker / app.py
alesamodio's picture
add wizard
bc4388d
# app.py
import os
from fastapi import FastAPI, Request, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from jose import jwt, JWTError
from supabase_ie import load_history_for_display
from datetime import datetime
from routes_utils import router as utils_router
from routes_stt import router as stt_router
from routes_wizard import router as wizard_router
from translate_query_response import (
detect_language_code,
translate_to_english,
translate_from_english,
)
from app_nn import run_chat_app # your Socrates logic
APP = FastAPI(title="Socrates API", version="1.0")
APP.include_router(utils_router)
APP.include_router(stt_router)
APP.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
APP.include_router(wizard_router)
# --- Supabase JWT secret (HS256) ---
JWT_SECRET = os.environ.get("SUPABASE_JWT_SECRET")
if not JWT_SECRET:
raise RuntimeError("SUPABASE_JWT_SECRET not set in environment")
async def verify_jwt(auth_header: str) -> str:
"""
Verify Supabase access token using shared JWT secret.
Return user_id (sub).
"""
if not auth_header or not auth_header.startswith("Bearer "):
raise HTTPException(status_code=401, detail="Missing Authorization header")
token = auth_header.split(" ", 1)[1]
try:
claims = jwt.decode(
token,
JWT_SECRET,
algorithms=["HS256"], # Supabase default
options={"verify_aud": False},
)
except JWTError as e:
print("JWT decode error:", repr(e))
raise HTTPException(status_code=401, detail=f"Invalid JWT: {e}")
user_id = claims.get("sub")
if not user_id:
raise HTTPException(status_code=401, detail="JWT has no sub (user id)")
return user_id
@APP.post("/chat/send")
async def chat_send(req: Request):
user_id = await verify_jwt(req.headers.get("authorization"))
data = await req.json()
message = data.get("message", "")
username = data.get("username") or "Anonymous"
profile = data.get("profile") or {}
ui_lang = data.get("ui_lang", "en")
reply = run_chat_app(
user_id=user_id,
username=username,
profile=profile,
ui_lang=ui_lang,
user_msg=message,
)
if isinstance(reply, dict):
news = reply.get("news_fetch")
if isinstance(news, dict):
news.pop("faiss_object", None)
return {"reply": reply, "user_id": user_id}
@APP.post("/chat/history")
async def chat_history(req: Request):
auth_header = req.headers.get("authorization", "")
try:
user_id = await verify_jwt(auth_header)
except Exception:
raise HTTPException(status_code=401, detail="Invalid JWT")
if not user_id:
raise HTTPException(status_code=401, detail="Invalid JWT")
msgs = load_history_for_display(user_id=user_id) or []
safe_messages = []
for i, m in enumerate(msgs):
safe_messages.append({
"id": m.get("id") or f"{i}-{m.get('role','assistant')}",
"role": m.get("role", "assistant"),
"content": m.get("content", ""),
"time": (
m.get("time")
or m.get("timestamp")
or datetime.utcnow().isoformat()
),
})
return {"messages": safe_messages}