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

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +41 -110
app.py CHANGED
@@ -1,157 +1,88 @@
1
  # app.py
2
  import os
3
- import warnings
4
  from dotenv import load_dotenv
5
- import gradio as gr
6
- from qdrant_search import QdrantSearch
7
- from langchain_groq import ChatGroq
8
- from nomic_embeddings import EmbeddingsModel
9
-
10
  from fastapi import FastAPI, HTTPException
11
  from fastapi.middleware.cors import CORSMiddleware
12
  from pydantic import BaseModel
 
 
 
13
 
14
- # Load environment variables
15
  load_dotenv()
16
 
17
- # Suppress FutureWarnings
18
  warnings.filterwarnings("ignore", category=FutureWarning)
19
 
20
- # Disable tokenizers parallelism
21
  os.environ["TOKENIZERS_PARALLELISM"] = "FALSE"
22
 
 
 
 
 
 
 
 
 
 
 
 
 
23
  # Initialize global variables
24
  collection_names = ["docs_v1_2", "docs_v2_2", "docs_v3_2"]
25
  limit = 5
26
-
27
- # Initialize the language model
28
  llm = ChatGroq(model="mixtral-8x7b-32768")
29
-
30
- # Initialize the embeddings model
31
  embeddings = EmbeddingsModel()
32
-
33
- # Initialize Qdrant search with necessary credentials
34
  search = QdrantSearch(
35
  qdrant_url=os.environ["QDRANT_CLOUD_URL"],
36
  api_key=os.environ["QDRANT_API_KEY"],
37
  embeddings=embeddings
38
  )
39
 
40
- def chat_function(question: str):
41
- """
42
- Handles the chat functionality by processing the user's question,
43
- retrieving relevant documents, generating an answer, and returning sources.
44
 
45
- Args:
46
- question (str): The user's question.
 
47
 
48
- Returns:
49
- Tuple[str, str]: The generated answer and the sources used.
50
- """
51
- query = question.strip()
52
  if not query:
53
- return "❌ **Error:** Query cannot be empty.", "No sources available."
54
 
55
  # Step 1: Retrieve relevant documents from Qdrant
56
  retrieved_docs = search.query_multiple_collections(query, collection_names, limit)
57
 
58
- if not retrieved_docs:
59
- return "⚠️ **No relevant documents found** for your query.", "No sources available."
60
-
61
  # Step 2: Prepare the context from retrieved documents
62
- context = "\n\n".join([doc['text'] for doc in retrieved_docs])
63
 
64
  # Step 3: Construct the prompt with context and question
65
  prompt = (
66
  "You are LangAssist, a knowledgeable assistant for the LangChain Python Library. "
67
  "Given the following context from the documentation, provide a helpful answer to the user's question.\n\n"
68
- "### Context:\n{context}\n\n"
69
- "### Question:\n{question}\n\n"
70
- "### Answer:"
71
  ).format(context=context, question=query)
72
 
73
  # Step 4: Generate an answer using the language model
74
  try:
75
  answer = llm.invoke(prompt)
76
  except Exception as e:
77
- return f"⚠️ **Error generating answer:** {str(e)}", "No sources available."
78
 
79
  # Prepare sources
80
- sources = "\n\n".join([
81
- f"**Source:** {doc['source']}\n**Excerpt:** {doc['text']}"
82
- for doc in retrieved_docs
83
- ])
84
-
85
- return answer.content.strip(), sources
86
-
87
- # Define Pydantic model for request
88
- class ChatRequest(BaseModel):
89
- question: str
90
-
91
- # Initialize FastAPI app
92
- app = FastAPI()
93
 
94
- # Define allowed origins
95
- origins = [
96
- "*", # Allow all origins; for production, specify your frontend domains
97
- # Example:
98
- # "http://localhost",
99
- # "http://localhost:3000",
100
- # "https://your-frontend-domain.com",
101
- ]
102
-
103
- # Add CORS middleware
104
- app.add_middleware(
105
- CORSMiddleware,
106
- allow_origins=origins, # Allows all origins. Replace "*" with specific domains in production.
107
- allow_credentials=True,
108
- allow_methods=["*"], # Allows all HTTP methods.
109
- allow_headers=["*"], # Allows all headers.
110
- )
111
-
112
- # Define API endpoint
113
- @app.post("/api/chat")
114
- async def api_chat(request: ChatRequest):
115
- try:
116
- answer, sources = chat_function(request.question)
117
- return {"answer": answer, "sources": sources}
118
- except Exception as e:
119
- raise HTTPException(status_code=500, detail=str(e))
120
 
121
- # Create Gradio Interface
122
- with gr.Blocks() as demo:
123
- gr.Markdown("# 🗨️ LangAssist Chat")
124
- gr.Markdown("Ask questions about the LangChain Python Library and get answers based on the latest documentation.")
125
-
126
- with gr.Row():
127
- with gr.Column(scale=2):
128
- question_input = gr.Textbox(
129
- lines=2,
130
- placeholder="Type your question here...",
131
- label="Your Question"
132
- )
133
- submit_button = gr.Button("💬 Submit")
134
- with gr.Column(scale=3):
135
- answer_output = gr.Markdown("### Answer will appear here...")
136
- sources_output = gr.Markdown("### Sources will appear here...")
137
-
138
- submit_button.click(
139
- fn=chat_function,
140
- inputs=question_input,
141
- outputs=[answer_output, sources_output]
142
- )
143
-
144
- gr.Markdown("""
145
- ---
146
- ## 📡 API Endpoint
147
-
148
- You can access the API endpoint at `/api/chat`. For example, send a POST request to `http://localhost:8000/api/chat` with JSON body `{"question": "Your question here"}`.
149
- """)
150
-
151
- # Mount Gradio app on FastAPI
152
- app = gr.mount_gradio_app(app, demo, path="/gradio")
153
-
154
- # To run, use: uvicorn app:app --host 0.0.0.0 --port 8000
155
- if __name__ == "__main__":
156
- import uvicorn
157
- uvicorn.run(app, host="0.0.0.0", port=8000)
 
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