DarshanaD commited on
Commit
2e58740
Β·
1 Parent(s): 71dae39

Initial commit

Browse files
Files changed (3) hide show
  1. README.md +2 -2
  2. app.py +535 -61
  3. requirements.txt +13 -1
README.md CHANGED
@@ -3,8 +3,8 @@ title: Pinecone Qdrant
3
  emoji: πŸ’¬
4
  colorFrom: yellow
5
  colorTo: purple
6
- sdk: gradio
7
- sdk_version: 5.0.1
8
  app_file: app.py
9
  pinned: false
10
  license: apache-2.0
 
3
  emoji: πŸ’¬
4
  colorFrom: yellow
5
  colorTo: purple
6
+ sdk: streamlit
7
+ sdk_version: 1.35.0
8
  app_file: app.py
9
  pinned: false
10
  license: apache-2.0
app.py CHANGED
@@ -1,64 +1,538 @@
1
- import gradio as gr
2
- from huggingface_hub import InferenceClient
3
-
4
- """
5
- For more information on `huggingface_hub` Inference API support, please check the docs: https://huggingface.co/docs/huggingface_hub/v0.22.2/en/guides/inference
6
- """
7
- client = InferenceClient("HuggingFaceH4/zephyr-7b-beta")
8
-
9
-
10
- def respond(
11
- message,
12
- history: list[tuple[str, str]],
13
- system_message,
14
- max_tokens,
15
- temperature,
16
- top_p,
17
- ):
18
- messages = [{"role": "system", "content": system_message}]
19
-
20
- for val in history:
21
- if val[0]:
22
- messages.append({"role": "user", "content": val[0]})
23
- if val[1]:
24
- messages.append({"role": "assistant", "content": val[1]})
25
-
26
- messages.append({"role": "user", "content": message})
27
-
28
- response = ""
29
-
30
- for message in client.chat_completion(
31
- messages,
32
- max_tokens=max_tokens,
33
- stream=True,
34
- temperature=temperature,
35
- top_p=top_p,
36
- ):
37
- token = message.choices[0].delta.content
38
-
39
- response += token
40
- yield response
41
-
42
-
43
- """
44
- For information on how to customize the ChatInterface, peruse the gradio docs: https://www.gradio.app/docs/chatinterface
45
- """
46
- demo = gr.ChatInterface(
47
- respond,
48
- additional_inputs=[
49
- gr.Textbox(value="You are a friendly Chatbot.", label="System message"),
50
- gr.Slider(minimum=1, maximum=2048, value=512, step=1, label="Max new tokens"),
51
- gr.Slider(minimum=0.1, maximum=4.0, value=0.7, step=0.1, label="Temperature"),
52
- gr.Slider(
53
- minimum=0.1,
54
- maximum=1.0,
55
- value=0.95,
56
- step=0.05,
57
- label="Top-p (nucleus sampling)",
58
- ),
59
- ],
60
- )
61
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62
 
63
  if __name__ == "__main__":
64
- demo.launch()
 
1
+ import streamlit as st
2
+ import boto3
3
+ import os
4
+ import tempfile
5
+ import sys
6
+ from typing import List, Dict, Any
7
+ from langchain.document_loaders import PyPDFLoader
8
+ from langchain.text_splitter import RecursiveCharacterTextSplitter
9
+ from langchain.embeddings import BedrockEmbeddings
10
+ from langchain.vectorstores import Pinecone as LangchainPinecone
11
+ from langchain.llms.bedrock import Bedrock
12
+ from langchain.chains import RetrievalQA
13
+ from langchain.schema import Document
14
+ from dotenv import load_dotenv
15
+ import warnings
16
+ warnings.filterwarnings("ignore")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
 
18
+ # Debug: Print Python environment and working directory
19
+ print("Python executable:", sys.executable)
20
+ print("Current working directory:", os.getcwd())
21
+
22
+ # Debug: Check if pinecone and qdrant-client are available
23
+ PINECONE_AVAILABLE = False
24
+ QDRANT_AVAILABLE = False
25
+
26
+ # Check for Pinecone
27
+ try:
28
+ from pinecone import Pinecone, ServerlessSpec
29
+ import pinecone
30
+ print("Pinecone version:", pinecone.__version__)
31
+ print("Pinecone module location:", pinecone.__file__)
32
+ PINECONE_AVAILABLE = True
33
+ except ImportError as e:
34
+ print("Failed to import Pinecone:", str(e))
35
+
36
+ # Check for Qdrant
37
+ try:
38
+ from qdrant_client import QdrantClient
39
+ from qdrant_client.models import Distance, VectorParams, PointStruct
40
+ from langchain.vectorstores import Qdrant
41
+ QDRANT_AVAILABLE = True
42
+ except ImportError as e:
43
+ print("Failed to import Qdrant:", str(e))
44
+
45
+ class ManagedVectorRAGChatbot:
46
+ def __init__(self):
47
+ self.embeddings = None
48
+ self.vectorstore = None
49
+ self.qa_chain = None
50
+ self.bedrock_client = None
51
+ self.documents_processed = False
52
+ self.session = None
53
+ self.vector_db_type = None
54
+
55
+ # Vector DB clients
56
+ self.pinecone_client = None
57
+ self.qdrant_client = None
58
+
59
+ # Load environment variables at initialization
60
+ self._load_env_vars()
61
+
62
+ # Automatically initialize Bedrock on instantiation
63
+ self.initialization_success, self.initialization_message = self.initialize_bedrock()
64
+
65
+ def _load_env_vars(self):
66
+ """Load environment variables from .env file with debugging."""
67
+ print("Attempting to load .env file...")
68
+ # Try to load .env from the current working directory
69
+ env_loaded = load_dotenv(override=True)
70
+ if not env_loaded:
71
+ # Fallback: Try the script's directory
72
+ script_dir = os.path.dirname(os.path.abspath(__file__))
73
+ env_path = os.path.join(script_dir, ".env")
74
+ print(f"Trying to load .env from: {env_path}")
75
+ env_loaded = load_dotenv(env_path, override=True)
76
+
77
+ if not env_loaded:
78
+ print("Warning: .env file not found. Using system environment variables if set.")
79
+ else:
80
+ print(".env file loaded successfully")
81
+
82
+ def _setup_aws_client(self):
83
+ """Set up the AWS Bedrock client with credentials from environment."""
84
+ try:
85
+ # Get AWS credentials from environment variables
86
+ aws_access_key = os.environ.get("AWS_ACCESS_KEY_ID")
87
+ aws_secret_key = os.environ.get("AWS_SECRET_ACCESS_KEY")
88
+ aws_region = os.environ.get("AWS_REGION", "us-east-1")
89
+
90
+ # Debug statements
91
+ print("AWS_ACCESS_KEY_ID:", aws_access_key)
92
+ print("AWS_REGION:", aws_region)
93
+
94
+ # Check if credentials are provided
95
+ if not aws_access_key or not aws_secret_key:
96
+ raise ValueError("AWS_ACCESS_KEY_ID or AWS_SECRET_ACCESS_KEY not found in environment")
97
+
98
+ # Create a boto3 session with the credentials
99
+ self.session = boto3.Session(
100
+ aws_access_key_id=aws_access_key,
101
+ aws_secret_access_key=aws_secret_key,
102
+ region_name=aws_region
103
+ )
104
+
105
+ # Create a Bedrock client
106
+ self.bedrock_client = self.session.client(
107
+ service_name='bedrock-runtime'
108
+ )
109
+ return True, "AWS Bedrock client initialized successfully!"
110
+ except Exception as e:
111
+ return False, f"Error setting up AWS client: {str(e)}"
112
+
113
+ def initialize_bedrock(self):
114
+ """Initialize AWS Bedrock client and embeddings."""
115
+ try:
116
+ # Set up AWS client using credentials from environment
117
+ success, message = self._setup_aws_client()
118
+ if not success:
119
+ return False, message
120
+
121
+ # Initialize Bedrock embeddings
122
+ self.embeddings = BedrockEmbeddings(
123
+ client=self.bedrock_client,
124
+ model_id="amazon.titan-embed-text-v1"
125
+ )
126
+
127
+ return True, "Bedrock initialized successfully!"
128
+ except Exception as e:
129
+ return False, f"Error initializing Bedrock: {str(e)}"
130
+
131
+ def initialize_pinecone(self):
132
+ """Initialize Pinecone vector database."""
133
+ if not PINECONE_AVAILABLE:
134
+ return False, f"Pinecone library not installed. Run: pip install pinecone. Error: {str(sys.exc_info()[1])}"
135
+
136
+ try:
137
+ api_key = os.environ.get("PINECONE_API_KEY")
138
+ index_name = os.environ.get("PINECONE_INDEX_NAME", "rag-chatbot-index")
139
+
140
+ print("PINECONE_API_KEY:", api_key)
141
+ print("PINECONE_INDEX_NAME:", index_name)
142
+
143
+ if not api_key:
144
+ return False, "PINECONE_API_KEY not found in environment"
145
+
146
+ # Initialize Pinecone with new client
147
+ pc = Pinecone(api_key=api_key)
148
+
149
+ # Check if index exists, create if not
150
+ existing_indexes = [index.name for index in pc.list_indexes()]
151
+
152
+ if index_name not in existing_indexes:
153
+ # Create index with dimension 1536 (Titan embeddings dimension)
154
+ pc.create_index(
155
+ name=index_name,
156
+ dimension=1536,
157
+ metric="cosine",
158
+ spec=ServerlessSpec(
159
+ cloud="aws",
160
+ region="us-east-1"
161
+ )
162
+ )
163
+ st.info(f"Created new Pinecone index: {index_name}")
164
+
165
+ # Connect to index
166
+ index = pc.Index(index_name)
167
+ self.pinecone_client = index
168
+ self.vector_db_type = "pinecone"
169
+
170
+ return True, f"Pinecone initialized successfully with index: {index_name}"
171
+
172
+ except Exception as e:
173
+ return False, f"Error initializing Pinecone: {str(e)}"
174
+
175
+ def initialize_qdrant(self):
176
+ """Initialize QDrant vector database."""
177
+ if not QDRANT_AVAILABLE:
178
+ return False, "QDrant library not installed. Run: pip install qdrant-client"
179
+
180
+ try:
181
+ url = os.environ.get("QDRANT_URL")
182
+ api_key = os.environ.get("QDRANT_API_KEY")
183
+
184
+ # Debug statements
185
+ print("QDRANT_URL:", url)
186
+ print("QDRANT_API_KEY:", api_key)
187
+
188
+ if not url:
189
+ return False, "QDRANT_URL not found in environment"
190
+ if not api_key:
191
+ return False, "QDRANT_API_KEY not found in environment"
192
+
193
+ # Initialize QDrant client
194
+ self.qdrant_client = QdrantClient(
195
+ url=url,
196
+ api_key=api_key,
197
+ )
198
+
199
+ # Test connection
200
+ collections = self.qdrant_client.get_collections()
201
+ self.vector_db_type = "qdrant"
202
+
203
+ return True, f"QDrant initialized successfully. Found {len(collections.collections)} collections."
204
+
205
+ except Exception as e:
206
+ return False, f"Error initializing QDrant: {str(e)}"
207
+
208
+ def process_pdf_with_pinecone(self, pdf_file) -> tuple[bool, str]:
209
+ """Process PDF file and create vector embeddings with Pinecone."""
210
+ try:
211
+ # Save uploaded file temporarily
212
+ with tempfile.NamedTemporaryFile(delete=False, suffix=".pdf") as tmp_file:
213
+ tmp_file.write(pdf_file.getvalue())
214
+ tmp_file_path = tmp_file.name
215
+
216
+ # Load PDF
217
+ loader = PyPDFLoader(tmp_file_path)
218
+ documents = loader.load()
219
+
220
+ # Split documents into chunks
221
+ text_splitter = RecursiveCharacterTextSplitter(
222
+ chunk_size=1000,
223
+ chunk_overlap=200,
224
+ length_function=len,
225
+ )
226
+ texts = text_splitter.split_documents(documents)
227
+
228
+ # Create Pinecone vector store
229
+ index_name = os.environ.get("PINECONE_INDEX_NAME", "rag-chatbot-index")
230
+
231
+ self.vectorstore = LangchainPinecone.from_documents(
232
+ documents=texts,
233
+ embedding=self.embeddings,
234
+ index_name=index_name,
235
+ namespace=None
236
+ )
237
+
238
+ # Initialize QA chain
239
+ self._initialize_qa_chain()
240
+
241
+ # Clean up temporary file
242
+ os.unlink(tmp_file_path)
243
+
244
+ self.documents_processed = True
245
+ return True, f"PDF processed successfully with Pinecone! Created {len(texts)} text chunks."
246
+
247
+ except Exception as e:
248
+ return False, f"Error processing PDF with Pinecone: {str(e)}"
249
+
250
+ def process_pdf_with_qdrant(self, pdf_file) -> tuple[bool, str]:
251
+ """Process PDF file and create vector embeddings with QDrant."""
252
+ try:
253
+ # Save uploaded file temporarily
254
+ with tempfile.NamedTemporaryFile(delete=False, suffix=".pdf") as tmp_file:
255
+ tmp_file.write(pdf_file.getvalue())
256
+ tmp_file_path = tmp_file.name
257
+
258
+ # Load PDF
259
+ loader = PyPDFLoader(tmp_file_path)
260
+ documents = loader.load()
261
+
262
+ # Split documents into chunks
263
+ text_splitter = RecursiveCharacterTextSplitter(
264
+ chunk_size=1000,
265
+ chunk_overlap=200,
266
+ length_function=len,
267
+ )
268
+ texts = text_splitter.split_documents(documents)
269
+
270
+ # Create QDrant vector store
271
+ collection_name = "rag_documents"
272
+
273
+ self.vectorstore = Qdrant.from_documents(
274
+ documents=texts,
275
+ embedding=self.embeddings,
276
+ url=os.environ.get("QDRANT_URL"),
277
+ api_key=os.environ.get("QDRANT_API_KEY"),
278
+ collection_name=collection_name,
279
+ force_recreate=True,
280
+ )
281
+
282
+ # Initialize QA chain
283
+ self._initialize_qa_chain()
284
+
285
+ # Clean up temporary file
286
+ os.unlink(tmp_file_path)
287
+
288
+ self.documents_processed = True
289
+ return True, f"PDF processed successfully with QDrant! Created {len(texts)} text chunks."
290
+
291
+ except Exception as e:
292
+ return False, f"Error processing PDF with QDrant: {str(e)}"
293
+
294
+ def _initialize_qa_chain(self):
295
+ """Initialize the QA chain with the vector store."""
296
+ # Initialize LLM
297
+ llm = Bedrock(
298
+ client=self.bedrock_client,
299
+ model_id="anthropic.claude-v2",
300
+ model_kwargs={
301
+ "max_tokens_to_sample": 512,
302
+ "temperature": 0.1,
303
+ "top_p": 0.9,
304
+ }
305
+ )
306
+
307
+ # Create QA chain
308
+ self.qa_chain = RetrievalQA.from_chain_type(
309
+ llm=llm,
310
+ chain_type="stuff",
311
+ retriever=self.vectorstore.as_retriever(
312
+ search_kwargs={"k": 3}
313
+ ),
314
+ return_source_documents=True
315
+ )
316
+
317
+ def query(self, question: str) -> Dict[str, Any]:
318
+ """Query the RAG system."""
319
+ if not self.qa_chain:
320
+ return {
321
+ "answer": "Please upload and process a PDF file first.",
322
+ "sources": []
323
+ }
324
+
325
+ try:
326
+ # Get response from QA chain
327
+ response = self.qa_chain({"query": question})
328
+
329
+ # Extract source information
330
+ sources = []
331
+ if "source_documents" in response:
332
+ for doc in response["source_documents"]:
333
+ sources.append({
334
+ "content": doc.page_content[:200] + "...",
335
+ "metadata": doc.metadata
336
+ })
337
+
338
+ return {
339
+ "answer": response["result"],
340
+ "sources": sources
341
+ }
342
+
343
+ except Exception as e:
344
+ return {
345
+ "answer": f"Error processing query: {str(e)}",
346
+ "sources": []
347
+ }
348
+
349
+ def main():
350
+ st.set_page_config(
351
+ page_title="Enhanced RAG Chatbot with Managed Vector DBs",
352
+ page_icon="πŸš€",
353
+ layout="wide"
354
+ )
355
+
356
+ st.title("πŸš€ Enhanced RAG Chatbot with Managed Vector Databases")
357
+ st.markdown("Upload a PDF document and chat with it using Amazon Bedrock + Pinecone/QDrant!")
358
+
359
+ # Initialize session state
360
+ if "chatbot" not in st.session_state:
361
+ st.session_state.chatbot = ManagedVectorRAGChatbot()
362
+
363
+ if "messages" not in st.session_state:
364
+ st.session_state.messages = []
365
+
366
+ if "bedrock_initialized" not in st.session_state:
367
+ st.session_state.bedrock_initialized = st.session_state.chatbot.initialization_success
368
+
369
+ if "vector_db_initialized" not in st.session_state:
370
+ st.session_state.vector_db_initialized = False
371
+
372
+ if "vector_db_type" not in st.session_state:
373
+ st.session_state.vector_db_type = None
374
+
375
+ # Sidebar for configuration and file upload
376
+ with st.sidebar:
377
+ st.header("πŸ”§ Configuration")
378
+
379
+ # Display Bedrock initialization status
380
+ if st.session_state.bedrock_initialized:
381
+ st.success("βœ… AWS Bedrock initialized")
382
+ else:
383
+ st.error("❌ " + st.session_state.chatbot.initialization_message)
384
+
385
+ st.markdown("---")
386
+
387
+ # Vector Database Selection
388
+ st.header("πŸ—ƒοΈ Vector Database")
389
+
390
+ vector_db_choice = st.selectbox(
391
+ "Choose Vector Database:",
392
+ ["Select...", "Pinecone", "QDrant"],
393
+ disabled=not st.session_state.bedrock_initialized
394
+ )
395
+
396
+ if vector_db_choice != "Select..." and st.session_state.bedrock_initialized:
397
+ if st.button(f"Initialize {vector_db_choice}"):
398
+ with st.spinner(f"Initializing {vector_db_choice}..."):
399
+ if vector_db_choice == "Pinecone":
400
+ success, message = st.session_state.chatbot.initialize_pinecone()
401
+ else: # QDrant
402
+ success, message = st.session_state.chatbot.initialize_qdrant()
403
+
404
+ if success:
405
+ st.success(message)
406
+ st.session_state.vector_db_initialized = True
407
+ st.session_state.vector_db_type = vector_db_choice.lower()
408
+ else:
409
+ st.error(message)
410
+
411
+ if st.session_state.vector_db_initialized:
412
+ st.success(f"βœ… {vector_db_choice} initialized")
413
+
414
+ st.markdown("---")
415
+
416
+ # File upload
417
+ st.header("πŸ“„ Document Upload")
418
+ uploaded_file = st.file_uploader(
419
+ "Choose a PDF file",
420
+ type="pdf",
421
+ disabled=not st.session_state.vector_db_initialized
422
+ )
423
+
424
+ if uploaded_file and st.session_state.vector_db_initialized:
425
+ if st.button("Process PDF"):
426
+ with st.spinner("Processing PDF..."):
427
+ if st.session_state.vector_db_type == "pinecone":
428
+ success, message = st.session_state.chatbot.process_pdf_with_pinecone(uploaded_file)
429
+ else: # qdrant
430
+ success, message = st.session_state.chatbot.process_pdf_with_qdrant(uploaded_file)
431
+
432
+ if success:
433
+ st.success(message)
434
+ else:
435
+ st.error(message)
436
+
437
+ # Main chat interface
438
+ col1, col2 = st.columns([2, 1])
439
+
440
+ with col1:
441
+ st.header("πŸ’¬ Chat Interface")
442
+
443
+ # Display chat messages
444
+ for message in st.session_state.messages:
445
+ with st.chat_message(message["role"]):
446
+ st.markdown(message["content"])
447
+
448
+ # Chat input
449
+ if prompt := st.chat_input("Ask a question about your document..."):
450
+ if not st.session_state.bedrock_initialized:
451
+ st.error("Bedrock initialization failed. Please check your environment variables and try again.")
452
+ st.stop()
453
+
454
+ if not st.session_state.vector_db_initialized:
455
+ st.error("Please initialize a vector database first!")
456
+ st.stop()
457
+
458
+ if not st.session_state.chatbot.documents_processed:
459
+ st.error("Please upload and process a PDF document first!")
460
+ st.stop()
461
+
462
+ # Add user message to chat history
463
+ st.session_state.messages.append({"role": "user", "content": prompt})
464
+ with st.chat_message("user"):
465
+ st.markdown(prompt)
466
+
467
+ # Get bot response
468
+ with st.chat_message("assistant"):
469
+ with st.spinner("Thinking..."):
470
+ response = st.session_state.chatbot.query(prompt)
471
+ st.markdown(response["answer"])
472
+
473
+ # Add assistant response to chat history
474
+ st.session_state.messages.append({
475
+ "role": "assistant",
476
+ "content": response["answer"]
477
+ })
478
+
479
+ with col2:
480
+ st.header("πŸ“Š System Status")
481
+
482
+ # Status indicators
483
+ if st.session_state.bedrock_initialized:
484
+ st.success("βœ… Bedrock Ready")
485
+ else:
486
+ st.error("❌ Bedrock Failed")
487
+
488
+ if st.session_state.vector_db_initialized:
489
+ st.success(f"βœ… {st.session_state.vector_db_type.title()} Ready")
490
+ else:
491
+ st.warning("⚠️ No Vector DB")
492
+
493
+ if st.session_state.chatbot.documents_processed:
494
+ st.success("βœ… Document Processed")
495
+ else:
496
+ st.info("πŸ“„ No Document")
497
+
498
+ if st.button("πŸ—‘οΈ Clear Chat"):
499
+ st.session_state.messages = []
500
+ st.rerun()
501
+
502
+ st.markdown("---")
503
+
504
+ # Comparison info
505
+ with st.expander("πŸ” Vector DB Comparison"):
506
+ st.markdown("""
507
+ **Pinecone:**
508
+ - βœ… Managed service, fully hosted
509
+ - βœ… Excellent performance & scaling
510
+ - βœ… Great documentation
511
+ - ⚠️ Pricing can add up
512
+
513
+ **QDrant:**
514
+ - βœ… Open source option
515
+ - βœ… Good performance
516
+ - βœ… More cost-effective
517
+ - βœ… Self-hosting available
518
+ """)
519
+
520
+ st.markdown("---")
521
+ st.markdown("""
522
+ ### πŸš€ How to use:
523
+ 1. Ensure AWS & vector DB credentials are set (in .env or environment)
524
+ 2. Choose Pinecone or QDrant
525
+ 3. Initialize your chosen vector database
526
+ 4. Upload a PDF file
527
+ 5. Process the PDF
528
+ 6. Start chatting!
529
+
530
+ ### ✨ Enhanced Features:
531
+ - Choose between Pinecone & QDrant
532
+ - Managed vector database hosting
533
+ - Better scalability & performance
534
+ - Production-ready architecture
535
+ """)
536
 
537
  if __name__ == "__main__":
538
+ main()
requirements.txt CHANGED
@@ -1 +1,13 @@
1
- huggingface_hub==0.25.2
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ langchain>=0.1.0
2
+ langchain-community>=0.0.10
3
+ unstructured
4
+ pypdf
5
+ huggingface_hub==0.25.2
6
+ streamlit
7
+ boto3
8
+ python-dotenv
9
+ pinecone
10
+
11
+ qdrant-client>=1.7.0
12
+ openai>=1.0.0
13
+ tiktoken>=0.5.0