avciTheProgrammer commited on
Commit
0ea9398
Β·
verified Β·
1 Parent(s): 3703052

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +50 -34
main.py CHANGED
@@ -5,7 +5,6 @@ from fastapi.middleware.cors import CORSMiddleware
5
  from pydantic import BaseModel
6
  from typing import Optional, List
7
  import httpx
8
- from supabase import create_client, Client
9
  from datetime import datetime
10
  import uuid
11
 
@@ -13,7 +12,7 @@ app = FastAPI(title="AI Team Chat API")
13
 
14
  app.add_middleware(
15
  CORSMiddleware,
16
- allow_origins=["*"], # Replace with your frontend URL in production
17
  allow_credentials=True,
18
  allow_methods=["*"],
19
  allow_headers=["*"],
@@ -22,15 +21,32 @@ app.add_middleware(
22
  # ─────────────────────────────────────────────
23
  # ENV VARS (set in HuggingFace Space secrets)
24
  # ─────────────────────────────────────────────
25
- GROQ_API_KEY = os.getenv("GROQ_API_KEY", "")
26
  OPENAI_API_KEY = os.getenv("OPENAI_API_KEY", "")
27
- SUPABASE_URL = os.getenv("SUPABASE_URL", "")
28
- SUPABASE_KEY = os.getenv("SUPABASE_KEY", "")
29
 
30
- # Supabase client (optional - graceful fallback if not configured)
31
- supabase: Optional[Client] = None
32
- if SUPABASE_URL and SUPABASE_KEY:
33
- supabase = create_client(SUPABASE_URL, SUPABASE_KEY)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
 
35
 
36
  # ─────────────────────────────────────────────
@@ -38,9 +54,9 @@ if SUPABASE_URL and SUPABASE_KEY:
38
  # ─────────────────────────────────────────────
39
  class ChatRequest(BaseModel):
40
  message: str
41
- provider: str = "groq" # "groq" or "openai"
42
- religion: Optional[str] = None # for Spiritual Coach
43
- session_id: Optional[str] = None # for Supabase history
44
  conversation_history: Optional[List[dict]] = []
45
 
46
 
@@ -63,9 +79,6 @@ class ChatResponse(BaseModel):
63
  # LLM WRAPPER
64
  # ─────────────────────────────────────────────
65
  async def call_llm(provider: str, system_prompt: str, user_message: str, temperature: float = 0.7) -> str:
66
- """
67
- Unified LLM wrapper. Supports Groq and OpenAI.
68
- """
69
  if provider == "groq":
70
  return await call_groq(system_prompt, user_message, temperature)
71
  elif provider == "openai":
@@ -75,14 +88,15 @@ async def call_llm(provider: str, system_prompt: str, user_message: str, tempera
75
 
76
 
77
  async def call_groq(system_prompt: str, user_message: str, temperature: float) -> str:
78
- if not GROQ_API_KEY:
79
- raise HTTPException(status_code=500, detail="GROQ_API_KEY not set")
 
80
 
81
  async with httpx.AsyncClient(timeout=30) as client:
82
  response = await client.post(
83
  "https://api.groq.com/openai/v1/chat/completions",
84
  headers={
85
- "Authorization": f"Bearer {GROQ_API_KEY}",
86
  "Content-Type": "application/json",
87
  },
88
  json={
@@ -101,14 +115,15 @@ async def call_groq(system_prompt: str, user_message: str, temperature: float) -
101
 
102
 
103
  async def call_openai(system_prompt: str, user_message: str, temperature: float) -> str:
104
- if not OPENAI_API_KEY:
105
- raise HTTPException(status_code=500, detail="OPENAI_API_KEY not set")
 
106
 
107
  async with httpx.AsyncClient(timeout=30) as client:
108
  response = await client.post(
109
  "https://api.openai.com/v1/chat/completions",
110
  headers={
111
- "Authorization": f"Bearer {OPENAI_API_KEY}",
112
  "Content-Type": "application/json",
113
  },
114
  json={
@@ -222,9 +237,9 @@ Question: <your single question here>"""
222
  # SUPABASE HELPERS
223
  # ─────────────────────────────────────────────
224
  async def save_to_supabase(session_id: str, user_message: str, agent_responses: list, summary: str, question: str):
225
- if not supabase:
 
226
  return
227
-
228
  try:
229
  record = {
230
  "session_id": session_id,
@@ -234,18 +249,18 @@ async def save_to_supabase(session_id: str, user_message: str, agent_responses:
234
  "question": question,
235
  "created_at": datetime.utcnow().isoformat(),
236
  }
237
- supabase.table("chat_history").insert(record).execute()
238
  except Exception as e:
239
- print(f"Supabase save error: {e}")
240
 
241
 
242
  async def get_session_history(session_id: str) -> list:
243
- if not supabase or not session_id:
 
244
  return []
245
-
246
  try:
247
  result = (
248
- supabase.table("chat_history")
249
  .select("*")
250
  .eq("session_id", session_id)
251
  .order("created_at", desc=False)
@@ -254,7 +269,7 @@ async def get_session_history(session_id: str) -> list:
254
  )
255
  return result.data or []
256
  except Exception as e:
257
- print(f"Supabase fetch error: {e}")
258
  return []
259
 
260
 
@@ -270,7 +285,7 @@ async def chat(request: ChatRequest):
270
  history_context = ""
271
  if request.conversation_history:
272
  history_lines = []
273
- for turn in request.conversation_history[-6:]: # last 3 exchanges
274
  history_lines.append(f"User: {turn.get('user', '')}")
275
  if turn.get("question"):
276
  history_lines.append(f"Team Question: {turn.get('question', '')}")
@@ -325,7 +340,7 @@ async def chat(request: ChatRequest):
325
  if not question:
326
  question = "Can you share more details so the team can help you better?"
327
 
328
- # ── Step 3: Save to Supabase ──
329
  agent_data = [r.dict() for r in agent_results]
330
  asyncio.create_task(
331
  save_to_supabase(session_id, request.message, agent_data, summary, question)
@@ -347,9 +362,10 @@ async def get_history(session_id: str):
347
 
348
  @app.get("/health")
349
  async def health():
 
350
  return {
351
  "status": "ok",
352
- "groq_configured": bool(GROQ_API_KEY),
353
- "openai_configured": bool(OPENAI_API_KEY),
354
- "supabase_configured": bool(supabase),
355
  }
 
5
  from pydantic import BaseModel
6
  from typing import Optional, List
7
  import httpx
 
8
  from datetime import datetime
9
  import uuid
10
 
 
12
 
13
  app.add_middleware(
14
  CORSMiddleware,
15
+ allow_origins=["*"],
16
  allow_credentials=True,
17
  allow_methods=["*"],
18
  allow_headers=["*"],
 
21
  # ─────────────────────────────────────────────
22
  # ENV VARS (set in HuggingFace Space secrets)
23
  # ─────────────────────────────────────────────
24
+ GROQ_API_KEY = os.getenv("GROQ_API_KEY", "")
25
  OPENAI_API_KEY = os.getenv("OPENAI_API_KEY", "")
26
+ SUPABASE_URL = os.getenv("SUPABASE_URL", "")
27
+ SUPABASE_KEY = os.getenv("SUPABASE_KEY", "")
28
 
29
+ # ─────────────────────────────────────────────
30
+ # SUPABASE β€” lazy init (never crashes startup)
31
+ # ─────────────────────────────────────────────
32
+ _supabase_client = None
33
+
34
+ def get_supabase():
35
+ global _supabase_client
36
+ if _supabase_client is not None:
37
+ return _supabase_client
38
+ url = os.getenv("SUPABASE_URL", "")
39
+ key = os.getenv("SUPABASE_KEY", "")
40
+ if not url or not key:
41
+ return None
42
+ try:
43
+ from supabase import create_client
44
+ _supabase_client = create_client(url, key)
45
+ print("Supabase connected successfully.")
46
+ return _supabase_client
47
+ except Exception as e:
48
+ print(f"Supabase init error (non-fatal): {e}")
49
+ return None
50
 
51
 
52
  # ─────────────────────────────────────────────
 
54
  # ─────────────────────────────────────────────
55
  class ChatRequest(BaseModel):
56
  message: str
57
+ provider: str = "groq"
58
+ religion: Optional[str] = None
59
+ session_id: Optional[str] = None
60
  conversation_history: Optional[List[dict]] = []
61
 
62
 
 
79
  # LLM WRAPPER
80
  # ─────────────────────────────────────────────
81
  async def call_llm(provider: str, system_prompt: str, user_message: str, temperature: float = 0.7) -> str:
 
 
 
82
  if provider == "groq":
83
  return await call_groq(system_prompt, user_message, temperature)
84
  elif provider == "openai":
 
88
 
89
 
90
  async def call_groq(system_prompt: str, user_message: str, temperature: float) -> str:
91
+ key = os.getenv("GROQ_API_KEY", "")
92
+ if not key:
93
+ raise HTTPException(status_code=500, detail="GROQ_API_KEY not set in environment")
94
 
95
  async with httpx.AsyncClient(timeout=30) as client:
96
  response = await client.post(
97
  "https://api.groq.com/openai/v1/chat/completions",
98
  headers={
99
+ "Authorization": f"Bearer {key}",
100
  "Content-Type": "application/json",
101
  },
102
  json={
 
115
 
116
 
117
  async def call_openai(system_prompt: str, user_message: str, temperature: float) -> str:
118
+ key = os.getenv("OPENAI_API_KEY", "")
119
+ if not key:
120
+ raise HTTPException(status_code=500, detail="OPENAI_API_KEY not set in environment")
121
 
122
  async with httpx.AsyncClient(timeout=30) as client:
123
  response = await client.post(
124
  "https://api.openai.com/v1/chat/completions",
125
  headers={
126
+ "Authorization": f"Bearer {key}",
127
  "Content-Type": "application/json",
128
  },
129
  json={
 
237
  # SUPABASE HELPERS
238
  # ─────────────────────────────────────────────
239
  async def save_to_supabase(session_id: str, user_message: str, agent_responses: list, summary: str, question: str):
240
+ db = get_supabase()
241
+ if not db:
242
  return
 
243
  try:
244
  record = {
245
  "session_id": session_id,
 
249
  "question": question,
250
  "created_at": datetime.utcnow().isoformat(),
251
  }
252
+ db.table("chat_history").insert(record).execute()
253
  except Exception as e:
254
+ print(f"Supabase save error (non-fatal): {e}")
255
 
256
 
257
  async def get_session_history(session_id: str) -> list:
258
+ db = get_supabase()
259
+ if not db or not session_id:
260
  return []
 
261
  try:
262
  result = (
263
+ db.table("chat_history")
264
  .select("*")
265
  .eq("session_id", session_id)
266
  .order("created_at", desc=False)
 
269
  )
270
  return result.data or []
271
  except Exception as e:
272
+ print(f"Supabase fetch error (non-fatal): {e}")
273
  return []
274
 
275
 
 
285
  history_context = ""
286
  if request.conversation_history:
287
  history_lines = []
288
+ for turn in request.conversation_history[-6:]:
289
  history_lines.append(f"User: {turn.get('user', '')}")
290
  if turn.get("question"):
291
  history_lines.append(f"Team Question: {turn.get('question', '')}")
 
340
  if not question:
341
  question = "Can you share more details so the team can help you better?"
342
 
343
+ # ── Step 3: Save to Supabase (non-blocking) ──
344
  agent_data = [r.dict() for r in agent_results]
345
  asyncio.create_task(
346
  save_to_supabase(session_id, request.message, agent_data, summary, question)
 
362
 
363
  @app.get("/health")
364
  async def health():
365
+ db = get_supabase()
366
  return {
367
  "status": "ok",
368
+ "groq_configured": bool(os.getenv("GROQ_API_KEY")),
369
+ "openai_configured": bool(os.getenv("OPENAI_API_KEY")),
370
+ "supabase_configured": bool(db),
371
  }