Tahasaif3 commited on
Commit
7b2e929
·
1 Parent(s): bc8e357

'changes'

Browse files
app/__pycache__/config.cpython-312.pyc CHANGED
Binary files a/app/__pycache__/config.cpython-312.pyc and b/app/__pycache__/config.cpython-312.pyc differ
 
app/__pycache__/database.cpython-312.pyc ADDED
Binary file (980 Bytes). View file
 
app/__pycache__/main.cpython-312.pyc ADDED
Binary file (1.62 kB). View file
 
app/__pycache__/qdrant_client.cpython-312.pyc ADDED
Binary file (1.81 kB). View file
 
app/config.py CHANGED
@@ -3,18 +3,15 @@ from pydantic_settings import BaseSettings
3
 
4
  class Settings(BaseSettings):
5
  OPENAI_API_KEY: str
6
- GEMINI_API_KEY: str
7
- # Set to "openai" or "gemini" to choose the AI provider
8
- AI_PROVIDER: str = "gemini"
9
  DATABASE_URL: str = os.getenv("DATABASE_URL", "")
10
  NEON_DATABASE_URL: str = os.getenv("NEON_DATABASE_URL", "")
11
  QDRANT_URL: str = os.getenv("QDRANT_URL", "http://localhost:6333")
12
  QDRANT_API_KEY: str = os.getenv("QDRANT_API_KEY", "")
13
  OPENAI_MODEL_CHAT: str = "gpt-4o-mini"
14
  OPENAI_MODEL_EMBEDDING: str = "text-embedding-3-small"
15
- GEMINI_MODEL_CHAT: str = "gemini-2.5-flash"
16
- GEMINI_MODEL_EMBEDDING: str = "embedding-001"
17
- GEMINI_OPENAI_COMPATIBLE_BASE_URL: str = "https://generativelanguage.googleapis.com/v1beta/openai/"
18
 
19
  class Config:
20
  env_file = ".env"
 
3
 
4
  class Settings(BaseSettings):
5
  OPENAI_API_KEY: str
6
+ GEMINI_API_KEY: str = ""
7
+ GEMINI_OPENAI_COMPATIBLE_BASE_URL: str = "https://generativelanguage.googleapis.com/v1beta"
8
+ AI_PROVIDER: str = "openai" # "openai" or "gemini"
9
  DATABASE_URL: str = os.getenv("DATABASE_URL", "")
10
  NEON_DATABASE_URL: str = os.getenv("NEON_DATABASE_URL", "")
11
  QDRANT_URL: str = os.getenv("QDRANT_URL", "http://localhost:6333")
12
  QDRANT_API_KEY: str = os.getenv("QDRANT_API_KEY", "")
13
  OPENAI_MODEL_CHAT: str = "gpt-4o-mini"
14
  OPENAI_MODEL_EMBEDDING: str = "text-embedding-3-small"
 
 
 
15
 
16
  class Config:
17
  env_file = ".env"
app/qdrant_client.py CHANGED
@@ -11,13 +11,6 @@ qdrant_client = QdrantClient(
11
 
12
  COLLECTION_NAME = "book_embeddings"
13
 
14
- def get_vector_size():
15
- """Get the appropriate vector size based on the AI provider"""
16
- if settings.AI_PROVIDER.lower() == "gemini":
17
- return 768 # Gemini embedding dimension
18
- else:
19
- return 1536 # OpenAI text-embedding-3-small dimension
20
-
21
  def init_qdrant_collection():
22
  """Initialize Qdrant collection if it doesn't exist"""
23
  try:
@@ -30,11 +23,11 @@ def init_qdrant_collection():
30
  qdrant_client.create_collection(
31
  collection_name=COLLECTION_NAME,
32
  vectors_config=VectorParams(
33
- size=get_vector_size(), # Dynamic vector size based on provider
34
  distance=Distance.COSINE
35
  )
36
  )
37
- print(f"✅ Created Qdrant collection: {COLLECTION_NAME} with {get_vector_size()} dimensions")
38
  else:
39
  print(f"✅ Qdrant collection already exists: {COLLECTION_NAME}")
40
  except Exception as e:
 
11
 
12
  COLLECTION_NAME = "book_embeddings"
13
 
 
 
 
 
 
 
 
14
  def init_qdrant_collection():
15
  """Initialize Qdrant collection if it doesn't exist"""
16
  try:
 
23
  qdrant_client.create_collection(
24
  collection_name=COLLECTION_NAME,
25
  vectors_config=VectorParams(
26
+ size=1536, # OpenAI text-embedding-3-small dimension
27
  distance=Distance.COSINE
28
  )
29
  )
30
+ print(f"✅ Created Qdrant collection: {COLLECTION_NAME}")
31
  else:
32
  print(f"✅ Qdrant collection already exists: {COLLECTION_NAME}")
33
  except Exception as e:
app/routes/__pycache__/chat.cpython-312.pyc ADDED
Binary file (3.29 kB). View file
 
app/routes/chat.py CHANGED
@@ -3,9 +3,8 @@ from qdrant_client import QdrantClient
3
  from app.qdrant_client import get_qdrant_client
4
  from app.schemas.chat import ChatRequest, ChatResponse, ChatSelectionRequest
5
  from app.services.rag_service import RAGService
6
- from app.services.embeddings_service import EmbeddingsService, GeminiEmbeddingsService
7
- from app.services.openai_service import OpenAIService, GeminiOpenAIService
8
- from app.config import settings
9
  import logging
10
 
11
  logger = logging.getLogger(__name__)
@@ -15,15 +14,9 @@ router = APIRouter(prefix="/api", tags=["chat"])
15
  def get_rag_service(
16
  qdrant_client: QdrantClient = Depends(get_qdrant_client)
17
  ):
18
- # Choose the appropriate services based on AI_PROVIDER setting
19
- if settings.AI_PROVIDER.lower() == "gemini":
20
- embeddings_service = GeminiEmbeddingsService()
21
- ai_service = GeminiOpenAIService()
22
- else:
23
- embeddings_service = EmbeddingsService()
24
- ai_service = OpenAIService()
25
-
26
- return RAGService(qdrant_client, embeddings_service, ai_service)
27
 
28
  @router.post("/chat", response_model=ChatResponse)
29
  async def chat(
@@ -34,7 +27,7 @@ async def chat(
34
  # Retrieve context from vector database
35
  context = await rag_service.retrieve_context(request.question, top_k=3)
36
 
37
- # Generate response using the configured AI service
38
  answer = await rag_service.generate_response(request.question, context)
39
 
40
  # Extract sources from context
 
3
  from app.qdrant_client import get_qdrant_client
4
  from app.schemas.chat import ChatRequest, ChatResponse, ChatSelectionRequest
5
  from app.services.rag_service import RAGService
6
+ from app.services.embeddings_service import get_embeddings_service
7
+ from app.services.openai_service import get_openai_service
 
8
  import logging
9
 
10
  logger = logging.getLogger(__name__)
 
14
  def get_rag_service(
15
  qdrant_client: QdrantClient = Depends(get_qdrant_client)
16
  ):
17
+ embeddings_service = get_embeddings_service()
18
+ openai_service = get_openai_service()
19
+ return RAGService(qdrant_client, embeddings_service, openai_service)
 
 
 
 
 
 
20
 
21
  @router.post("/chat", response_model=ChatResponse)
22
  async def chat(
 
27
  # Retrieve context from vector database
28
  context = await rag_service.retrieve_context(request.question, top_k=3)
29
 
30
+ # Generate response using OpenAI
31
  answer = await rag_service.generate_response(request.question, context)
32
 
33
  # Extract sources from context
app/schemas/__pycache__/chat.cpython-312.pyc ADDED
Binary file (1.47 kB). View file
 
app/services/__pycache__/embeddings_service.cpython-312.pyc ADDED
Binary file (2.62 kB). View file
 
app/services/__pycache__/openai_service.cpython-312.pyc CHANGED
Binary files a/app/services/__pycache__/openai_service.cpython-312.pyc and b/app/services/__pycache__/openai_service.cpython-312.pyc differ
 
app/services/__pycache__/rag_service.cpython-312.pyc ADDED
Binary file (2.63 kB). View file
 
app/services/embeddings_service.py CHANGED
@@ -34,4 +34,11 @@ class GeminiEmbeddingsService:
34
  input=[text],
35
  model=self.model
36
  )
37
- return response.data[0].embedding
 
 
 
 
 
 
 
 
34
  input=[text],
35
  model=self.model
36
  )
37
+ return response.data[0].embedding
38
+
39
+ # Factory function to get the appropriate embeddings service
40
+ def get_embeddings_service():
41
+ if settings.AI_PROVIDER.lower() == "gemini":
42
+ return GeminiEmbeddingsService()
43
+ else:
44
+ return EmbeddingsService()
app/services/openai_service.py CHANGED
@@ -43,4 +43,11 @@ class GeminiOpenAIService:
43
  model=self.model,
44
  messages=messages
45
  )
46
- return response.choices[0].message.content
 
 
 
 
 
 
 
 
43
  model=self.model,
44
  messages=messages
45
  )
46
+ return response.choices[0].message.content
47
+
48
+ # Factory function to get the appropriate OpenAI service
49
+ def get_openai_service():
50
+ if settings.AI_PROVIDER.lower() == "gemini":
51
+ return GeminiOpenAIService()
52
+ else:
53
+ return OpenAIService()
app/services/rag_service.py CHANGED
@@ -3,18 +3,22 @@ from qdrant_client import QdrantClient
3
  from qdrant_client.models import NamedVector
4
  from typing import List
5
 
 
6
  from app.services.openai_service import OpenAIService, GeminiOpenAIService
7
  from app.services.embeddings_service import EmbeddingsService, GeminiEmbeddingsService
8
 
 
 
 
 
9
  class RAGService:
10
- def __init__(self, qdrant_client: QdrantClient, embeddings_service: EmbeddingsService, ai_service: OpenAIService):
11
  self.qdrant_client = qdrant_client
12
  self.embeddings_service = embeddings_service
13
- self.ai_service = ai_service
14
  self.collection_name = os.getenv("QDRANT_COLLECTION_NAME", "book_embeddings")
15
 
16
  async def retrieve_context(self, query: str, top_k: int = 3) -> List[str]:
17
- # Handle both OpenAI and Gemini embeddings
18
  query_vector = await self.embeddings_service.create_embedding(query)
19
 
20
  search_result = self.qdrant_client.search(
@@ -33,6 +37,5 @@ class RAGService:
33
  Question: {query}
34
 
35
  Answer:"""
36
- # Handle both OpenAI and Gemini services
37
- response = await self.ai_service.get_chat_response(full_prompt)
38
  return response
 
3
  from qdrant_client.models import NamedVector
4
  from typing import List
5
 
6
+ # We'll use the base classes for type hints
7
  from app.services.openai_service import OpenAIService, GeminiOpenAIService
8
  from app.services.embeddings_service import EmbeddingsService, GeminiEmbeddingsService
9
 
10
+ # Type alias for either service
11
+ AIEmbeddingService = EmbeddingsService | GeminiEmbeddingsService
12
+ AIOpenAIService = OpenAIService | GeminiOpenAIService
13
+
14
  class RAGService:
15
+ def __init__(self, qdrant_client: QdrantClient, embeddings_service: AIEmbeddingService, openai_service: AIOpenAIService):
16
  self.qdrant_client = qdrant_client
17
  self.embeddings_service = embeddings_service
18
+ self.openai_service = openai_service
19
  self.collection_name = os.getenv("QDRANT_COLLECTION_NAME", "book_embeddings")
20
 
21
  async def retrieve_context(self, query: str, top_k: int = 3) -> List[str]:
 
22
  query_vector = await self.embeddings_service.create_embedding(query)
23
 
24
  search_result = self.qdrant_client.search(
 
37
  Question: {query}
38
 
39
  Answer:"""
40
+ response = await self.openai_service.get_chat_response(full_prompt)
 
41
  return response
scripts/ingest_content.py CHANGED
@@ -11,9 +11,8 @@ from dotenv import load_dotenv
11
  import sys
12
  sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
13
 
14
- from app.services.embeddings_service import EmbeddingsService, GeminiEmbeddingsService
15
- from app.qdrant_client import get_qdrant_client, get_vector_size
16
- from app.config import settings
17
 
18
  load_dotenv(dotenv_path=Path(__file__).resolve().parent.parent / ".env")
19
 
@@ -36,15 +35,12 @@ def chunk_text(text: str, chunk_size: int = 1000, overlap: int = 200) -> list[st
36
  async def ingest_content(
37
  docs_path: Path,
38
  qdrant_client: QdrantClient,
39
- embeddings_service: EmbeddingsService,
40
  collection_name: str,
41
  ):
42
- # Determine vector size based on the embedding service
43
- vector_size = get_vector_size()
44
-
45
  qdrant_client.recreate_collection(
46
  collection_name=collection_name,
47
- vectors_config=VectorParams(size=vector_size, distance=Distance.COSINE),
48
  )
49
 
50
  points = []
@@ -96,12 +92,7 @@ if __name__ == "__main__":
96
  args = parser.parse_args()
97
 
98
  qdrant_client = get_qdrant_client()
99
-
100
- # Choose the appropriate embedding service based on AI_PROVIDER setting
101
- if settings.AI_PROVIDER.lower() == "gemini":
102
- embeddings_service = GeminiEmbeddingsService()
103
- else:
104
- embeddings_service = EmbeddingsService()
105
 
106
  # Run the async ingestion
107
  import asyncio
 
11
  import sys
12
  sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
13
 
14
+ from app.services.embeddings_service import get_embeddings_service
15
+ from app.qdrant_client import get_qdrant_client
 
16
 
17
  load_dotenv(dotenv_path=Path(__file__).resolve().parent.parent / ".env")
18
 
 
35
  async def ingest_content(
36
  docs_path: Path,
37
  qdrant_client: QdrantClient,
38
+ embeddings_service,
39
  collection_name: str,
40
  ):
 
 
 
41
  qdrant_client.recreate_collection(
42
  collection_name=collection_name,
43
+ vectors_config=VectorParams(size=1536, distance=Distance.COSINE), # OpenAI embeddings size
44
  )
45
 
46
  points = []
 
92
  args = parser.parse_args()
93
 
94
  qdrant_client = get_qdrant_client()
95
+ embeddings_service = get_embeddings_service()
 
 
 
 
 
96
 
97
  # Run the async ingestion
98
  import asyncio