Vela commited on
Commit
6ccb49e
·
1 Parent(s): ed7e26f

added pinecone db

Browse files
chroma.log ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ WARNING: [10-03-2025 20:07:32] chroma_server_nofile is not supported on Windows. chroma_server_nofile will not be set.
2
+ WARNING: [10-03-2025 20:07:51] chroma_server_nofile is not supported on Windows. chroma_server_nofile will not be set.
3
+ INFO: [10-03-2025 20:07:52] Anonymized telemetry enabled. See https://docs.trychroma.com/telemetry for more information.
4
+ DEBUG: [10-03-2025 20:07:52] Starting component System
5
+ DEBUG: [10-03-2025 20:07:52] Starting component OpenTelemetryClient
6
+ DEBUG: [10-03-2025 20:07:52] Starting component SqliteDB
7
+ DEBUG: [10-03-2025 20:07:52] Starting component SimpleQuotaEnforcer
8
+ DEBUG: [10-03-2025 20:07:52] Starting component Posthog
9
+ DEBUG: [10-03-2025 20:07:52] Starting component SimpleRateLimitEnforcer
10
+ DEBUG: [10-03-2025 20:07:52] Starting component LocalSegmentManager
11
+ DEBUG: [10-03-2025 20:07:52] Starting component LocalExecutor
12
+ DEBUG: [10-03-2025 20:07:52] Starting component SegmentAPI
13
+ DEBUG: [10-03-2025 20:07:52] Starting component SimpleAsyncRateLimitEnforcer
14
+ INFO: [10-03-2025 20:07:52] Started server process [17592]
15
+ INFO: [10-03-2025 20:07:52] Waiting for application startup.
16
+ INFO: [10-03-2025 20:07:52] Application startup complete.
17
+ INFO: [10-03-2025 20:07:52] Uvicorn running on http://localhost:8000 (Press CTRL+C to quit)
18
+ INFO: [10-03-2025 20:16:05] ::1:57148 - "GET /api/v2/auth/identity HTTP/1.1" 200
19
+ INFO: [10-03-2025 20:16:05] ::1:57149 - "GET /api/v2/tenants/default_tenant HTTP/1.1" 200
20
+ INFO: [10-03-2025 20:16:05] ::1:57149 - "GET /api/v2/tenants/default_tenant/databases/default_database HTTP/1.1" 200
src/backend/__pycache__/main.cpython-313.pyc CHANGED
Binary files a/src/backend/__pycache__/main.cpython-313.pyc and b/src/backend/__pycache__/main.cpython-313.pyc differ
 
src/backend/data/__pycache__/chroma_db.cpython-313.pyc CHANGED
Binary files a/src/backend/data/__pycache__/chroma_db.cpython-313.pyc and b/src/backend/data/__pycache__/chroma_db.cpython-313.pyc differ
 
src/backend/data/__pycache__/pinecone_db.cpython-313.pyc ADDED
Binary file (7.41 kB). View file
 
src/backend/data/chroma_db.py CHANGED
@@ -1,4 +1,5 @@
1
  import chromadb
 
2
  from utils import logger
3
  from chromadb.utils import embedding_functions
4
  default_ef = embedding_functions.DefaultEmbeddingFunction()
@@ -12,6 +13,11 @@ DB_PATH = "./src/backend/vector-db"
12
  # Initialize ChromaDB Client
13
  client = chromadb.PersistentClient(path=DB_PATH)
14
 
 
 
 
 
 
15
  collection = client.get_or_create_collection(
16
  name=COLLECTION_NAME,
17
  embedding_function=default_ef,
 
1
  import chromadb
2
+ import asyncio
3
  from utils import logger
4
  from chromadb.utils import embedding_functions
5
  default_ef = embedding_functions.DefaultEmbeddingFunction()
 
13
  # Initialize ChromaDB Client
14
  client = chromadb.PersistentClient(path=DB_PATH)
15
 
16
+
17
+
18
+ # chroma_client = chromadb.HttpClient(host='localhost', port=8000)
19
+ # client = chromadb.AsyncHttpClient()
20
+
21
  collection = client.get_or_create_collection(
22
  name=COLLECTION_NAME,
23
  embedding_function=default_ef,
src/backend/data/pinecone_db.py ADDED
@@ -0,0 +1,144 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import sys
3
+ src_directory = os.path.abspath(os.path.join(os.path.dirname(__file__), "../..", "backend"))
4
+ sys.path.append(src_directory)
5
+ from pinecone import Pinecone, ServerlessSpec
6
+ import time
7
+ from tqdm import tqdm # Progress bar for large datasets
8
+ from dotenv import load_dotenv
9
+ from utils import logger
10
+ import pandas as pd
11
+ from models import embedding_model
12
+ from data import dataset
13
+
14
+ load_dotenv()
15
+ PINECONE_API_KEY = os.environ.get("PINECONE_API_KEY")
16
+ logger = logger.get_logger()
17
+ NAMESPACE = "health-care-dataset"
18
+ INDEX_NAME = "health-care-index"
19
+
20
+
21
+ def create_index(pinecone, index_name):
22
+ pinecone.create_index(
23
+ name=index_name,
24
+ dimension=384,
25
+ metric="cosine",
26
+ spec=ServerlessSpec(
27
+ cloud="aws",
28
+ region="us-east-1"
29
+ )
30
+ )
31
+
32
+ def wait_till_index_loaded(pinecone, index_name):
33
+ while True:
34
+ index = pinecone.describe_index(index_name)
35
+ if index.status.get("ready", False):
36
+ index = pinecone.Index(index_name)
37
+ logger.info(f"Index '{index_name}' is ready and is now accessible.")
38
+ return index
39
+ else:
40
+ logger.debug(f"Index '{index_name}' is not ready yet. Checking again in 1 second.")
41
+ time.sleep(1)
42
+
43
+ def get_index():
44
+ global index
45
+ index = None
46
+ try:
47
+ pc = Pinecone(api_key=PINECONE_API_KEY)
48
+ index_name = INDEX_NAME
49
+ logger.info(f"Checking if the index '{index_name}' exists...")
50
+ if not pc.has_index(index_name):
51
+ logger.info(f"Index '{index_name}' does not exist. Creating a new index...")
52
+ create_index(pc,index_name)
53
+ logger.info(f"Index '{index_name}' creation initiated. Waiting for it to be ready...")
54
+ index = wait_till_index_loaded(pc,index_name)
55
+ else:
56
+ index = pc.Index(index_name)
57
+ logger.info(f"Index '{index_name}' already exists. Returning the existing index.")
58
+ except Exception as e:
59
+ logger.info(f"Error occurred while getting or creating the Pinecone index: {str(e)}", exc_info=True)
60
+ return index
61
+
62
+ index = get_index()
63
+
64
+ def process_and_upsert_data(index, data: pd.DataFrame):
65
+
66
+ # Validate if the required columns exist in the row (Series)
67
+ try:
68
+ logger.info("Started upserting the data to database")
69
+ for idx, row in data.iterrows():
70
+ logger.info(f"Processing row {row['input']}")
71
+ input_text = row['input']
72
+ output_text = row['output']
73
+ instruction_text = row['instruction']
74
+ if not isinstance(input_text, str) or not input_text.strip():
75
+ logger.warning(f"Skipping row {idx} due to empty or invalid input text.")
76
+ continue
77
+ row_dict = {
78
+ "question": input_text,
79
+ "answer" : output_text,
80
+ "instruction": instruction_text
81
+ }
82
+ embeddings = embedding_model.get_text_embedding(row['input'])
83
+ index.upsert(
84
+ vectors=[{
85
+ "id": f"id{idx}",
86
+ "values": embeddings,
87
+ "metadata":row_dict
88
+ }],
89
+ namespace=NAMESPACE,
90
+ )
91
+ logger.info(f"Successfully upserted data for question {input_text} with answer {output_text}")
92
+ except Exception as e:
93
+ logger.error(f"Error processing row with index {idx}: {e}")
94
+
95
+ def search_vector_store(query, n_result : int = 3) -> list[dict]:
96
+ """
97
+ Searches the vector store for the most relevant matches based on the given query.
98
+
99
+ This method retrieves the top `n_result` closest matches from the vector store
100
+ using an embedding-based similarity search. Each match includes metadata
101
+ such as the answer, instruction, and question.
102
+
103
+ Args:
104
+ query (str): The search query text.
105
+ n_result (int, optional): The number of top results to retrieve. Defaults to 3.
106
+
107
+ Returns:
108
+ list[dict]: A list of dictionaries, where each dictionary contains:
109
+ - "answer" (str): The retrieved answer.
110
+ - "instruction" (str): The instruction related to the answer.
111
+ - "question" (str): The question associated with the answer.
112
+
113
+ Raises:
114
+ Exception: If an error occurs while querying the vector store.
115
+
116
+ """
117
+ try:
118
+ index = get_index()
119
+ embedding = embedding_model.get_text_embedding(query)
120
+ response = index.query(
121
+ top_k=n_result,
122
+ vector=embedding,
123
+ namespace=NAMESPACE,
124
+ include_metadata=True)
125
+ metadata = []
126
+ for response in response['matches']:
127
+ metadata.append({"answer":response['metadata']['answer'],
128
+ "instruction":response['metadata']['instruction'],
129
+ "question":response['metadata']['question']})
130
+ return metadata
131
+ except Exception as e:
132
+ raise Exception(f"Error occurred while searching the vector store: {str(e)}")
133
+
134
+ def get_retrieved_context(prompt: str) -> str:
135
+ response = search_vector_store(prompt)
136
+ if response and "metadatas" in response and response["metadatas"]:
137
+ retrieved_contexts = [metadata["answer"] for metadata in response["metadatas"][0]]
138
+ return "\n".join(retrieved_contexts[:3])
139
+ return "No relevant information found in the database."
140
+
141
+ data_set = dataset.get_data_set()[6139:10000]
142
+ process_and_upsert_data(index, data_set)
143
+ # response = search_vector_store("What is the treatment for diabetes?")
144
+ # print(response)
src/backend/main.py CHANGED
@@ -3,4 +3,5 @@ from routes import chat_api
3
 
4
  app = FastAPI()
5
 
6
- app.include_router(chat_api.router, prefix="/chat", tags=["chat"])
 
 
3
 
4
  app = FastAPI()
5
 
6
+ app.include_router(chat_api.router, prefix="/chat", tags=["chat"])
7
+ # app.include_router(upsert_data.router, prefix="/data", tags=["data"])
src/backend/models/__pycache__/embedding_model.cpython-313.pyc ADDED
Binary file (1.31 kB). View file
 
src/backend/models/embedding_model.py ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from sentence_transformers import SentenceTransformer
2
+ from utils import logger
3
+ from fastapi import UploadFile
4
+ from PIL import Image
5
+
6
+ logger = logger.get_logger()
7
+
8
+ model = SentenceTransformer("all-MiniLM-L6-v2")
9
+
10
+ def get_text_embedding(search_query: str):
11
+ try:
12
+ logger.info(f"Getting embedding for the text: {search_query}")
13
+ text_embedding = model.encode(search_query, convert_to_tensor=True).cpu().numpy().tolist()
14
+ logger.info("Text embedding successfully retrieved.")
15
+ return text_embedding
16
+ except Exception as e:
17
+ logger.error(f"Error while getting embedding for text: {e}")
18
+ raise
src/backend/routes/__pycache__/chat_api.cpython-313.pyc CHANGED
Binary files a/src/backend/routes/__pycache__/chat_api.cpython-313.pyc and b/src/backend/routes/__pycache__/chat_api.cpython-313.pyc differ
 
src/backend/routes/__pycache__/upsert_data.cpython-313.pyc ADDED
Binary file (187 Bytes). View file
 
src/backend/routes/chat_api.py CHANGED
@@ -2,7 +2,8 @@ from fastapi import APIRouter, HTTPException
2
  from utils import logger
3
  from models.schemas import Chat_Response, ChatRequest
4
  from models import llm_model
5
- from data import chroma_db
 
6
 
7
  logger = logger.get_logger()
8
  router = APIRouter()
@@ -23,9 +24,9 @@ async def get_db_response(chat_request: Chat_Response):
23
  try:
24
  logger.info(f"Received user prompt: {chat_request.prompt}")
25
  query = chat_request.prompt[-1]
26
- response_text = chroma_db.search_vector_store(query)
27
  logger.info(f"Retrieved context for user prompt: {chat_request.prompt[:50]}...")
28
- return {"status": "success", "response": response_text}
29
  except Exception as e:
30
  logger.exception("Unexpected error occurred while processing the request.")
31
  raise HTTPException(status_code=500, detail="An error occurred while processing your request.")
@@ -37,4 +38,6 @@ async def chat_with_assistant(request: ChatRequest):
37
  response = llm_model.get_medical_assistant_request(request.conversation_history)
38
  return {"response": response}
39
  except Exception as e:
40
- raise HTTPException(status_code=500, detail=str(e))
 
 
 
2
  from utils import logger
3
  from models.schemas import Chat_Response, ChatRequest
4
  from models import llm_model
5
+ from data import pinecone_db
6
+ # from data import chroma_db
7
 
8
  logger = logger.get_logger()
9
  router = APIRouter()
 
24
  try:
25
  logger.info(f"Received user prompt: {chat_request.prompt}")
26
  query = chat_request.prompt[-1]
27
+ response_text = pinecone_db.search_vector_store(query)
28
  logger.info(f"Retrieved context for user prompt: {chat_request.prompt[:50]}...")
29
+ return response_text
30
  except Exception as e:
31
  logger.exception("Unexpected error occurred while processing the request.")
32
  raise HTTPException(status_code=500, detail="An error occurred while processing your request.")
 
38
  response = llm_model.get_medical_assistant_request(request.conversation_history)
39
  return {"response": response}
40
  except Exception as e:
41
+ raise HTTPException(status_code=500, detail=str(e))
42
+
43
+ # Input format for above endpoint
src/backend/routes/upsert_data.py ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # from fastapi import APIRouter,HTTPException
2
+ # from data import dataset
3
+ # from data import pinecone_db
4
+
5
+ # router = APIRouter()
6
+ # index_name = "question-answering-index"
7
+
8
+ # @router.post("/upsert_data")
9
+ # async def upsert_data():
10
+ # try:
11
+ # df = dataset.get_data_set()[0:1000]
12
+ # pinecone_db.process_and_upsert_data(index_name, df)
13
+ # return {"status": "success"}
14
+ # except Exception as e:
15
+ # raise HTTPException(status_code=500, detail=str(e))