Maslan34 commited on
Commit
a94c300
·
1 Parent(s): 45e1847
Files changed (1) hide show
  1. app.py +116 -25
app.py CHANGED
@@ -37,72 +37,108 @@ class GeminiRAGChatbotCPU:
37
  self.llm = None
38
  self.embeddings = None
39
  self.retriever = None
 
40
 
41
  def gemini_yukle(self):
 
42
  self.llm = ChatGoogleGenerativeAI(
43
  model=self.model_variant,
44
  google_api_key=GEMINI_API_KEY,
45
  temperature=0.2,
46
  max_output_tokens=200,
47
  )
 
48
  return self.llm
49
 
50
  def embedding_yukle(self):
51
  model = "emrecan/bert-base-turkish-cased-mean-nli-stsb-tr"
 
52
  self.embeddings = HuggingFaceEmbeddings(
53
  model_name=model,
54
  model_kwargs={'device': self.device},
55
  encode_kwargs={'normalize_embeddings': True}
56
  )
 
57
  return self.embeddings
58
 
59
  def dokumanlari_yukle(self, klasor_yolu: str):
 
 
60
  if not os.path.exists(klasor_yolu):
 
61
  os.makedirs(klasor_yolu)
62
  return []
 
63
  documents = []
 
 
64
  for root, _, files in os.walk(klasor_yolu):
65
  for f in files:
66
  path = os.path.join(root, f)
67
  if f.endswith(".txt"):
68
- with open(path, "r", encoding="utf-8") as t:
69
- text = t.read()
70
- documents.append(Document(page_content=text, metadata={"source": f}))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
71
  return documents
72
 
73
  def metni_parcala(self, documents: List):
 
74
  text_splitter = RecursiveCharacterTextSplitter(
75
  chunk_size=450,
76
  chunk_overlap=50,
77
  length_function=len,
78
  separators=["\n\n", "\n", ".", "!", "?", ";", ":", " ", ""]
79
  )
80
- return text_splitter.split_documents(documents)
 
 
81
 
82
  def vektor_db_olustur(self, chunks: List, db_yolu):
 
 
 
 
 
 
83
  if os.path.exists(db_yolu):
 
84
  import shutil
85
  shutil.rmtree(db_yolu)
 
 
86
  self.vectordb = Chroma.from_documents(chunks, self.embeddings, persist_directory=db_yolu)
 
87
  return self.vectordb
88
 
89
  def format_docs(self, docs):
90
  return "\n\n".join(doc.page_content for doc in docs)
91
 
92
  def chatbot_olustur(self, k=5):
 
93
  self.retriever = self.vectordb.as_retriever(search_type="similarity", search_kwargs={"k": k})
94
  template = """Sen Gemini, Türkçe konuşan bir süpermarket asistanısın.
95
-
96
  Bağlam:
97
  {context}
98
-
99
  Soru: {question}
100
-
101
  Kurallar:
102
  - Sadece bağlamdaki bilgilerle cevap ver
103
  - Kısa ve net ol
104
  - Bilgi yoksa "Bu konuda bilgim yok" de
105
-
106
  Cevap:"""
107
  prompt = ChatPromptTemplate.from_template(template)
108
  self.rag_chain = (
@@ -111,20 +147,46 @@ Cevap:"""
111
  | self.llm
112
  | StrOutputParser()
113
  )
 
114
  return self.rag_chain
115
 
116
  def soru_sor(self, soru: str):
117
- cevap = self.rag_chain.invoke(soru)
118
- return {"cevap": cevap.strip()}
 
 
 
 
 
 
119
 
120
  def setup(self, init=True, db_yolu="./chroma_db", dokuman_klasoru="./documents", k=5):
121
- self.embedding_yukle()
122
- self.gemini_yukle()
123
- if init:
124
- docs = self.dokumanlari_yukle(dokuman_klasoru)
125
- chunks = self.metni_parcala(docs)
126
- self.vektor_db_olustur(chunks, db_yolu)
127
- self.chatbot_olustur(k)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
128
 
129
 
130
  # =========================================================
@@ -136,9 +198,20 @@ gemini = None
136
  @asynccontextmanager
137
  async def lifespan(app: FastAPI):
138
  global gemini
139
- gemini = GeminiRAGChatbotCPU()
140
- gemini.setup(init=True)
 
 
 
 
 
 
 
 
 
141
  yield
 
 
142
 
143
  app = FastAPI(lifespan=lifespan, title="Gemini Chatbot API")
144
 
@@ -152,12 +225,30 @@ app.add_middleware(
152
 
153
  @app.get("/")
154
  async def root():
155
- return {"status": "ok"}
 
156
 
157
  @app.post("/api/chat")
158
  async def chat(request: Request):
159
- data = await request.json()
160
- soru = data.get("message", "")
161
- if not soru:
162
- raise HTTPException(status_code=400, detail="Message required")
163
- return gemini.soru_sor(soru)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
  self.llm = None
38
  self.embeddings = None
39
  self.retriever = None
40
+ logger.info(f"🤖 GeminiRAGChatbotCPU başlatıldı - Model: {model_variant}")
41
 
42
  def gemini_yukle(self):
43
+ logger.info("📡 Gemini API yükleniyor...")
44
  self.llm = ChatGoogleGenerativeAI(
45
  model=self.model_variant,
46
  google_api_key=GEMINI_API_KEY,
47
  temperature=0.2,
48
  max_output_tokens=200,
49
  )
50
+ logger.info("✅ Gemini API yüklendi")
51
  return self.llm
52
 
53
  def embedding_yukle(self):
54
  model = "emrecan/bert-base-turkish-cased-mean-nli-stsb-tr"
55
+ logger.info(f"📚 Embedding modeli yükleniyor: {model}")
56
  self.embeddings = HuggingFaceEmbeddings(
57
  model_name=model,
58
  model_kwargs={'device': self.device},
59
  encode_kwargs={'normalize_embeddings': True}
60
  )
61
+ logger.info("✅ Embedding modeli yüklendi")
62
  return self.embeddings
63
 
64
  def dokumanlari_yukle(self, klasor_yolu: str):
65
+ logger.info(f"📁 Dokümanlar yükleniyor: {klasor_yolu}")
66
+
67
  if not os.path.exists(klasor_yolu):
68
+ logger.warning(f"⚠️ Klasör bulunamadı, oluşturuluyor: {klasor_yolu}")
69
  os.makedirs(klasor_yolu)
70
  return []
71
+
72
  documents = []
73
+ file_count = 0
74
+
75
  for root, _, files in os.walk(klasor_yolu):
76
  for f in files:
77
  path = os.path.join(root, f)
78
  if f.endswith(".txt"):
79
+ try:
80
+ with open(path, "r", encoding="utf-8") as t:
81
+ text = t.read()
82
+ documents.append(Document(page_content=text, metadata={"source": f}))
83
+ file_count += 1
84
+ logger.info(f" ✓ Yüklendi: {f} ({len(text)} karakter)")
85
+ except Exception as e:
86
+ logger.error(f" ✗ Yüklenemedi: {f} - Hata: {e}")
87
+
88
+ logger.info(f"✅ Toplam {file_count} doküman yüklendi")
89
+
90
+ if file_count == 0:
91
+ logger.warning("⚠️ Hiç doküman bulunamadı! Varsayılan içerik ekleniyor...")
92
+ documents = [Document(
93
+ page_content="Global AI Hub, yapay zeka eğitimleri sunan bir platformdur.",
94
+ metadata={"source": "default.txt"}
95
+ )]
96
+
97
  return documents
98
 
99
  def metni_parcala(self, documents: List):
100
+ logger.info(f"✂️ Dokümanlar parçalanıyor ({len(documents)} doküman)...")
101
  text_splitter = RecursiveCharacterTextSplitter(
102
  chunk_size=450,
103
  chunk_overlap=50,
104
  length_function=len,
105
  separators=["\n\n", "\n", ".", "!", "?", ";", ":", " ", ""]
106
  )
107
+ chunks = text_splitter.split_documents(documents)
108
+ logger.info(f"✅ {len(chunks)} chunk oluşturuldu")
109
+ return chunks
110
 
111
  def vektor_db_olustur(self, chunks: List, db_yolu):
112
+ logger.info(f"🗄️ Vector DB oluşturuluyor: {db_yolu}")
113
+
114
+ if not chunks or len(chunks) == 0:
115
+ logger.error("❌ HATA: Chunks listesi boş!")
116
+ raise ValueError("Chunks listesi boş, vector DB oluşturulamıyor!")
117
+
118
  if os.path.exists(db_yolu):
119
+ logger.info(f" ⚠️ Mevcut DB siliniyor: {db_yolu}")
120
  import shutil
121
  shutil.rmtree(db_yolu)
122
+
123
+ logger.info(f" 📊 {len(chunks)} chunk ile DB oluşturuluyor...")
124
  self.vectordb = Chroma.from_documents(chunks, self.embeddings, persist_directory=db_yolu)
125
+ logger.info("✅ Vector DB oluşturuldu")
126
  return self.vectordb
127
 
128
  def format_docs(self, docs):
129
  return "\n\n".join(doc.page_content for doc in docs)
130
 
131
  def chatbot_olustur(self, k=5):
132
+ logger.info(f"💬 Chatbot oluşturuluyor (k={k})...")
133
  self.retriever = self.vectordb.as_retriever(search_type="similarity", search_kwargs={"k": k})
134
  template = """Sen Gemini, Türkçe konuşan bir süpermarket asistanısın.
 
135
  Bağlam:
136
  {context}
 
137
  Soru: {question}
 
138
  Kurallar:
139
  - Sadece bağlamdaki bilgilerle cevap ver
140
  - Kısa ve net ol
141
  - Bilgi yoksa "Bu konuda bilgim yok" de
 
142
  Cevap:"""
143
  prompt = ChatPromptTemplate.from_template(template)
144
  self.rag_chain = (
 
147
  | self.llm
148
  | StrOutputParser()
149
  )
150
+ logger.info("✅ Chatbot oluşturuldu")
151
  return self.rag_chain
152
 
153
  def soru_sor(self, soru: str):
154
+ logger.info(f"❓ Soru alındı: {soru[:50]}...")
155
+ try:
156
+ cevap = self.rag_chain.invoke(soru)
157
+ logger.info(f"💬 Cevap üretildi: {cevap[:50]}...")
158
+ return {"cevap": cevap.strip()}
159
+ except Exception as e:
160
+ logger.error(f"❌ Cevap üretme hatası: {e}")
161
+ raise
162
 
163
  def setup(self, init=True, db_yolu="./chroma_db", dokuman_klasoru="./documents", k=5):
164
+ logger.info("=" * 60)
165
+ logger.info("🚀 SETUP BAŞLATILIYOR")
166
+ logger.info("=" * 60)
167
+
168
+ try:
169
+ self.embedding_yukle()
170
+ self.gemini_yukle()
171
+
172
+ if init:
173
+ docs = self.dokumanlari_yukle(dokuman_klasoru)
174
+ chunks = self.metni_parcala(docs)
175
+ self.vektor_db_olustur(chunks, db_yolu)
176
+
177
+ self.chatbot_olustur(k)
178
+
179
+ logger.info("=" * 60)
180
+ logger.info("✅ SETUP TAMAMLANDI")
181
+ logger.info("=" * 60)
182
+
183
+ except Exception as e:
184
+ logger.error("=" * 60)
185
+ logger.error(f"❌ SETUP HATASI: {e}")
186
+ logger.error("=" * 60)
187
+ import traceback
188
+ traceback.print_exc()
189
+ raise
190
 
191
 
192
  # =========================================================
 
198
  @asynccontextmanager
199
  async def lifespan(app: FastAPI):
200
  global gemini
201
+ logger.info("🌟 FastAPI Uygulama Başlatılıyor...")
202
+
203
+ try:
204
+ gemini = GeminiRAGChatbotCPU()
205
+ gemini.setup(init=True)
206
+ logger.info("🎉 Uygulama başarıyla başlatıldı!")
207
+ except Exception as e:
208
+ logger.error(f"💥 Uygulama başlatma hatası: {e}")
209
+ import traceback
210
+ traceback.print_exc()
211
+
212
  yield
213
+
214
+ logger.info("👋 Uygulama kapatılıyor...")
215
 
216
  app = FastAPI(lifespan=lifespan, title="Gemini Chatbot API")
217
 
 
225
 
226
  @app.get("/")
227
  async def root():
228
+ logger.info("🏠 Root endpoint çağrıldı")
229
+ return {"status": "ok", "message": "Gemini Chatbot API çalışıyor"}
230
 
231
  @app.post("/api/chat")
232
  async def chat(request: Request):
233
+ try:
234
+ data = await request.json()
235
+ soru = data.get("message", "")
236
+
237
+ logger.info(f"📨 API çağrısı alındı - Message: {soru[:50]}...")
238
+
239
+ if not soru:
240
+ logger.warning("⚠️ Boş mesaj gönderildi")
241
+ raise HTTPException(status_code=400, detail="Message required")
242
+
243
+ sonuc = gemini.soru_sor(soru)
244
+
245
+ logger.info(f"✅ Başarılı cevap döndürüldü")
246
+ return sonuc
247
+
248
+ except HTTPException:
249
+ raise
250
+ except Exception as e:
251
+ logger.error(f"❌ API hatası: {e}")
252
+ import traceback
253
+ traceback.print_exc()
254
+ raise HTTPException(status_code=500, detail=str(e))