Jaita commited on
Commit
7bea0f0
·
verified ·
1 Parent(s): 0ef51b1

Create main.py

Browse files
Files changed (1) hide show
  1. main.py +123 -0
main.py ADDED
@@ -0,0 +1,123 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import requests
3
+ from fastapi import FastAPI, HTTPException
4
+ from fastapi.middleware.cors import CORSMiddleware
5
+ from pydantic import BaseModel
6
+ from services.kb_creation import collection, ingest_documents, search_knowledge_base
7
+ from contextlib import asynccontextmanager
8
+ import google.generativeai as genai
9
+
10
+ os.environ["POSTHOG_DISABLED"] = "true" # Disable PostHog telemetry
11
+
12
+
13
+ # --- 0. Config ---
14
+ GEMINI_API_KEY = os.getenv("GEMINI_API_KEY")
15
+ if not GEMINI_API_KEY:
16
+ raise RuntimeError("GEMINI_API_KEY is not set in environment.")
17
+
18
+ # Configure the SDK
19
+ genai.configure(api_key=GEMINI_API_KEY)
20
+
21
+ # Choose the model
22
+ MODEL_NAME = "gemini-2.5-flash-lite"
23
+ model = genai.GenerativeModel(MODEL_NAME)
24
+
25
+
26
+
27
+ # --- Initialize FastAPI ---
28
+ #app = FastAPI()
29
+ @asynccontextmanager
30
+ async def lifespan(app: FastAPI):
31
+ try:
32
+ folder_path = os.path.join(os.getcwd(), "documents")
33
+ if collection.count() == 0:
34
+ print("🔍 KB empty. Running ingestion...")
35
+ ingest_documents(folder_path)
36
+ else:
37
+ print(f"✅ KB already populated with {collection.count()} entries. Skipping ingestion.")
38
+ except Exception as e:
39
+ print(f"⚠️ KB ingestion failed: {e}")
40
+ yield
41
+
42
+ app = FastAPI(lifespan=lifespan)
43
+
44
+ # --- Configure CORS ---
45
+ origins = [
46
+ "https://jaita-chatbot-react-frontend-v1.hf.space"
47
+ #"https://jaita-chatbot-fastapi-backend.hf.space/chat",
48
+ ]
49
+
50
+ app.add_middleware(
51
+ CORSMiddleware,
52
+ allow_origins=origins,
53
+ allow_credentials=True,
54
+ allow_methods=["*"],
55
+ allow_headers=["*"],
56
+ )
57
+
58
+ # --- Define the Request Data Structure ---
59
+ class ChatInput(BaseModel):
60
+ user_message: str
61
+
62
+ # --- Gemini API Setup ---
63
+ GEMINI_API_KEY = os.getenv("GEMINI_API_KEY")
64
+ GEMINI_URL = f"https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash-lite:generateContent?key={GEMINI_API_KEY}"
65
+
66
+ # --- Endpoints ---
67
+ @app.get("/")
68
+ async def health_check():
69
+ return {"status": "ok"}
70
+
71
+
72
+ @app.post("/chat")
73
+ async def chat_with_ai(input_data: ChatInput):
74
+ """Handle chat interactions using Google Generative AI via requests."""
75
+ try:
76
+ # Retrieve relevant documents from knowledge base
77
+ kb_results = search_knowledge_base(input_data.user_message, top_k=10)
78
+ #print(f"kb_results are: {kb_results}")
79
+
80
+ # Extract relevant context from search results
81
+ context = ""
82
+ relevant_docs=[]
83
+ if kb_results and kb_results.get('documents'):
84
+ # Limit context to avoid token limits - take top 2 most relevant
85
+ relevant_docs = kb_results['documents'][0][:2]
86
+ context = "\n\n".join(relevant_docs)
87
+
88
+ # Construct enhanced prompt with context
89
+ if context:
90
+ enhanced_prompt = f"""Use the following knowledge base context to answer the user's question accurately.
91
+ If the context contains relevant information, base your answer on it.
92
+ If the context doesn't help, say you're raising a ticket and provide a ticket number.
93
+ Knowledge Base Context:
94
+ {context}
95
+ User Question: {input_data.user_message}
96
+ Answer:"""
97
+ else:
98
+ enhanced_prompt = f"User Question: {input_data.user_message}\n\nAnswer:"
99
+ headers = {"Content-Type": "application/json"}
100
+ payload = {
101
+ "contents": [
102
+ {
103
+ "parts": [{"text": enhanced_prompt}]
104
+ }
105
+ ]
106
+ }
107
+
108
+ response = requests.post(GEMINI_URL, headers=headers, json=payload, verify=False)
109
+ result = response.json()
110
+ #print("result",result)
111
+ # Extract Gemini's response
112
+ bot_response = result["candidates"][0]["content"]["parts"][0]["text"]
113
+
114
+ # Include debug info in response
115
+ debug_info = f"Context found: {'Yes' if context else 'No'}"
116
+ if context:
117
+ debug_info += f" (Top {len(relevant_docs)} documents used)"
118
+
119
+ return {"bot_response": bot_response, "debug": debug_info}
120
+
121
+
122
+ except Exception as e:
123
+ raise HTTPException(status_code=500, detail=str(e))