Tanmay09516 commited on
Commit
ebd67e4
·
verified ·
1 Parent(s): 1a48792

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +90 -53
app.py CHANGED
@@ -1,88 +1,125 @@
1
- # app.py
2
  import os
 
3
  from dotenv import load_dotenv
4
- from fastapi import FastAPI, HTTPException
5
- from fastapi.middleware.cors import CORSMiddleware
6
- from pydantic import BaseModel
7
  from qdrant_search import QdrantSearch
8
  from langchain_groq import ChatGroq
9
  from nomic_embeddings import EmbeddingsModel
10
 
 
 
 
 
11
  load_dotenv()
12
 
13
- import warnings
14
  warnings.filterwarnings("ignore", category=FutureWarning)
15
 
 
16
  os.environ["TOKENIZERS_PARALLELISM"] = "FALSE"
17
 
18
- # Initialize FastAPI app
19
- app = FastAPI()
20
 
21
- # Allow CORS for frontend on Vercel
22
- app.add_middleware(
23
- CORSMiddleware,
24
- allow_origins=["*"], # Replace "*" with your frontend URL for better security
25
- allow_credentials=True,
26
- allow_methods=["*"],
27
- allow_headers=["*"],
28
- )
 
 
29
 
30
  # Initialize global variables
31
  collection_names = ["docs_v1_2", "docs_v2_2", "docs_v3_2"]
32
  limit = 5
33
- llm = ChatGroq(model="mixtral-8x7b-32768")
34
- embeddings = EmbeddingsModel()
35
- search = QdrantSearch(
36
- qdrant_url=os.environ["QDRANT_CLOUD_URL"],
37
- api_key=os.environ["QDRANT_API_KEY"],
38
  embeddings=embeddings
39
  )
40
 
41
- # Define request and response models
42
- class QueryRequest(BaseModel):
43
- question: str
 
 
 
 
44
 
45
- class AnswerResponse(BaseModel):
46
- answer: str
47
- sources: list
48
 
49
- # API endpoint to handle user queries
50
- @app.post("/api/chat", response_model=AnswerResponse)
51
- async def chat_endpoint(request: QueryRequest):
52
- query = request.question.strip()
53
  if not query:
54
- raise HTTPException(status_code=400, detail="Query cannot be empty.")
55
 
56
  # Step 1: Retrieve relevant documents from Qdrant
57
  retrieved_docs = search.query_multiple_collections(query, collection_names, limit)
58
 
 
 
 
 
 
 
59
  # Step 2: Prepare the context from retrieved documents
60
- context = "\n".join([doc['text'] for doc in retrieved_docs])
61
-
62
- # Step 3: Construct the prompt with context and question
63
- prompt = (
64
- "You are LangAssist, a knowledgeable assistant for the LangChain Python Library. "
65
- "Given the following context from the documentation, provide a helpful answer to the user's question.\n\n"
66
- "Context:\n{context}\n\n"
67
- "Question: {question}\n\n"
68
- "Answer:"
69
- ).format(context=context, question=query)
70
-
71
- # Step 4: Generate an answer using the language model
72
  try:
73
  answer = llm.invoke(prompt)
74
  except Exception as e:
75
- raise HTTPException(status_code=500, detail=str(e))
76
 
77
  # Prepare sources
78
- sources = [
79
- {
80
- "source": doc['source'],
81
- "text": doc['text']
82
- } for doc in retrieved_docs
83
- ]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
84
 
85
- # Step 5: Return the answer and sources
86
- # return AnswerResponse(answer=answer.strip(), sources=sources)
87
- return AnswerResponse(answer=answer.content.strip(), sources=sources)
88
 
 
 
 
 
1
  import os
2
+ import warnings
3
  from dotenv import load_dotenv
4
+ import gradio as gr
5
+
6
+
7
  from qdrant_search import QdrantSearch
8
  from langchain_groq import ChatGroq
9
  from nomic_embeddings import EmbeddingsModel
10
 
11
+
12
+
13
+
14
+ # Load environment variables from .env file
15
  load_dotenv()
16
 
17
+ # Suppress FutureWarnings
18
  warnings.filterwarnings("ignore", category=FutureWarning)
19
 
20
+ # Disable tokenizers parallelism to avoid potential issues
21
  os.environ["TOKENIZERS_PARALLELISM"] = "FALSE"
22
 
 
 
23
 
24
+
25
+
26
+
27
+
28
+
29
+
30
+
31
+
32
+
33
+
34
 
35
  # Initialize global variables
36
  collection_names = ["docs_v1_2", "docs_v2_2", "docs_v3_2"]
37
  limit = 5
 
 
 
 
 
38
  embeddings=embeddings
39
  )
40
 
41
+ def chat_endpoint(question: str):
42
+ """
43
+ Handles the chat functionality by processing the user's question,
44
+ retrieving relevant documents, generating an answer, and returning sources.
45
+
46
+ Args:
47
+ question (str): The user's question.
48
 
 
 
 
49
 
50
+ Returns:
51
+ Tuple[str, str]: The generated answer and the sources used.
52
+ """
53
+ query = question.strip()
54
  if not query:
55
+ return "❌ **Error:** Query cannot be empty.", "No sources available."
56
 
57
  # Step 1: Retrieve relevant documents from Qdrant
58
  retrieved_docs = search.query_multiple_collections(query, collection_names, limit)
59
 
60
+ if not retrieved_docs:
61
+ return "⚠️ **No relevant documents found** for your query.", "No sources available."
62
+
63
+
64
+
65
+
66
  # Step 2: Prepare the context from retrieved documents
67
+ context = "\n\n".join([doc['text'] for doc in retrieved_docs])
 
 
 
 
 
 
 
 
 
 
 
68
  try:
69
  answer = llm.invoke(prompt)
70
  except Exception as e:
71
+ return f"⚠️ **Error generating answer:** {str(e)}", "No sources available."
72
 
73
  # Prepare sources
74
+ sources_md = "\n\n".join([
75
+ f"**Source:** {src['source']}\n**Excerpt:** {src['text']}"
76
+ for src in retrieved_docs
77
+ ])
78
+
79
+ return answer.content.strip(), sources_md
80
+
81
+
82
+
83
+
84
+
85
+
86
+
87
+
88
+
89
+
90
+
91
+
92
+
93
+
94
+
95
+
96
+
97
+
98
+
99
+
100
+
101
+
102
+
103
+
104
+
105
+ # Create Gradio Interface
106
+ interface = gr.Interface(
107
+ fn=chat_endpoint,
108
+ inputs=gr.Textbox(
109
+ lines=2,
110
+ placeholder="Type your question here...",
111
+ description="Ask questions about the LangChain Python Library and get answers based on the latest documentation."
112
+ )
113
+
114
+ # If running locally, uncomment the following lines:
115
+
116
+
117
+
118
+
119
+
120
+
121
+
122
 
 
 
 
123
 
124
+ # if __name__ == "__main__":
125
+ # interface.launch()