Hammad712 commited on
Commit
aa4bd46
·
verified ·
1 Parent(s): 8e81d90

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +75 -65
main.py CHANGED
@@ -1,5 +1,6 @@
1
  import os
2
  import zipfile
 
3
  from fastapi import FastAPI, HTTPException
4
  from pydantic import BaseModel
5
 
@@ -9,6 +10,13 @@ from langchain_groq import ChatGroq
9
  from langchain.chains import RetrievalQA
10
  from langchain.prompts import PromptTemplate
11
 
 
 
 
 
 
 
 
12
  app = FastAPI()
13
 
14
  # === Globals ===
@@ -25,60 +33,55 @@ class QueryRequest(BaseModel):
25
  def load_components():
26
  global llm, embeddings, vectorstore, retriever, chain
27
 
28
- # 1) Init LLM & Embeddings
29
- llm = ChatGroq(
30
- model="meta-llama/llama-4-scout-17b-16e-instruct",
31
- temperature=0,
32
- max_tokens=1024,
33
- api_key=os.getenv("API_KEY"),
34
- )
35
- embeddings = HuggingFaceEmbeddings(
36
- model_name="intfloat/multilingual-e5-large",
37
- model_kwargs={"device": "cpu"},
38
- encode_kwargs={"normalize_embeddings": True},
39
- )
40
-
41
- # 2) Unzip & Load both FAISS vectorstores
42
- # First index
43
- zip1 = "faiss_index.zip"
44
- dir1 = "faiss_index"
45
- if not os.path.exists(dir1):
46
- with zipfile.ZipFile(zip1, 'r') as z:
47
- z.extractall(dir1)
48
- print("✅ Unzipped FAISS index 1.")
49
- vs1 = FAISS.load_local(
50
- dir1,
51
- embeddings,
52
- allow_dangerous_deserialization=True
53
- )
54
- print("✅ FAISS index 1 loaded.")
55
-
56
- # Second index
57
- zip2 = "faiss_index(1).zip"
58
- dir2 = "faiss_index_extra"
59
- if not os.path.exists(dir2):
60
- with zipfile.ZipFile(zip2, 'r') as z:
61
- z.extractall(dir2)
62
- print("✅ Unzipped FAISS index 2.")
63
- vs2 = FAISS.load_local(
64
- dir2,
65
- embeddings,
66
- allow_dangerous_deserialization=True
67
- )
68
- print(" FAISS index 2 loaded.")
69
-
70
- # 3) Merge them
71
- vs1.merge_from(vs2)
72
- vectorstore = vs1
73
- print("✅ Merged FAISS indexes into a single vectorstore.")
74
-
75
- # 4) Create retriever & QA chain
76
- retriever = vectorstore.as_retriever(search_kwargs={"k": 3})
77
- prompt = PromptTemplate(
78
- template="""
79
  You are an expert assistant on Islamic knowledge.
80
- Use **only** the information in the “Retrieved context” to answer the user’s question.
81
- Do **not** add any outside information, personal opinions, or conjecture—if the answer is not contained in the context, reply with “لا أعلم”.
82
  Be concise, accurate, and directly address the user’s question.
83
 
84
  Retrieved context:
@@ -89,16 +92,20 @@ User’s question:
89
 
90
  Your response:
91
  """,
92
- input_variables=["context", "question"],
93
- )
94
- chain = RetrievalQA.from_chain_type(
95
- llm=llm,
96
- chain_type="stuff",
97
- retriever=retriever,
98
- return_source_documents=False,
99
- chain_type_kwargs={"prompt": prompt},
100
- )
101
- print("QA chain ready.")
 
 
 
 
102
 
103
  @app.get("/")
104
  def root():
@@ -107,7 +114,10 @@ def root():
107
  @app.post("/query")
108
  def query(request: QueryRequest):
109
  try:
 
110
  result = chain.invoke({"query": request.question})
111
- return {"answer": result["result"]}
 
112
  except Exception as e:
113
- raise HTTPException(status_code=500, detail=str(e))
 
 
1
  import os
2
  import zipfile
3
+ import logging
4
  from fastapi import FastAPI, HTTPException
5
  from pydantic import BaseModel
6
 
 
10
  from langchain.chains import RetrievalQA
11
  from langchain.prompts import PromptTemplate
12
 
13
+ # Configure logging
14
+ logging.basicConfig(
15
+ level=logging.INFO,
16
+ format="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
17
+ )
18
+ logger = logging.getLogger(__name__)
19
+
20
  app = FastAPI()
21
 
22
  # === Globals ===
 
33
  def load_components():
34
  global llm, embeddings, vectorstore, retriever, chain
35
 
36
+ try:
37
+ # 1) Init LLM & Embeddings
38
+ llm = ChatGroq(
39
+ model="meta-llama/llama-4-scout-17b-16e-instruct",
40
+ temperature=0,
41
+ max_tokens=1024,
42
+ api_key=os.getenv("API_KEY"),
43
+ )
44
+ embeddings = HuggingFaceEmbeddings(
45
+ model_name="intfloat/multilingual-e5-large",
46
+ model_kwargs={"device": "cpu"},
47
+ encode_kwargs={"normalize_embeddings": True},
48
+ )
49
+
50
+ # 2) Unzip & Load both FAISS vectorstores
51
+ for zip_name, dir_name in [("faiss_index.zip", "faiss_index"), ("faiss_index(1).zip", "faiss_index_extra")]:
52
+ if not os.path.exists(dir_name):
53
+ with zipfile.ZipFile(zip_name, 'r') as z:
54
+ z.extractall(dir_name)
55
+ logger.info(f"Unzipped {zip_name} to {dir_name}.")
56
+ else:
57
+ logger.info(f"Directory {dir_name} already exists.")
58
+
59
+ vs1 = FAISS.load_local(
60
+ "faiss_index",
61
+ embeddings,
62
+ allow_dangerous_deserialization=True
63
+ )
64
+ logger.info("FAISS index 1 loaded.")
65
+
66
+ vs2 = FAISS.load_local(
67
+ "faiss_index_extra",
68
+ embeddings,
69
+ allow_dangerous_deserialization=True
70
+ )
71
+ logger.info("FAISS index 2 loaded.")
72
+
73
+ # 3) Merge them
74
+ vs1.merge_from(vs2)
75
+ vectorstore = vs1
76
+ logger.info("Merged FAISS indexes into a single vectorstore.")
77
+
78
+ # 4) Create retriever & QA chain
79
+ retriever = vectorstore.as_retriever(search_kwargs={"k": 3})
80
+ prompt = PromptTemplate(
81
+ template="""
 
 
 
 
 
82
  You are an expert assistant on Islamic knowledge.
83
+ Use **only** the information in the “Retrieved context” to answer general questions related to Islam.
84
+ Do **not** add any outside information, personal opinions, or conjecture—if the answer is not contained in the context, reply with "I don't know".
85
  Be concise, accurate, and directly address the user’s question.
86
 
87
  Retrieved context:
 
92
 
93
  Your response:
94
  """,
95
+ input_variables=["context", "question"],
96
+ )
97
+ chain = RetrievalQA.from_chain_type(
98
+ llm=llm,
99
+ chain_type="stuff",
100
+ retriever=retriever,
101
+ return_source_documents=False,
102
+ chain_type_kwargs={"prompt": prompt},
103
+ )
104
+ logger.info("QA chain ready.")
105
+
106
+ except Exception as e:
107
+ logger.error("Error loading components", exc_info=True)
108
+ raise
109
 
110
  @app.get("/")
111
  def root():
 
114
  @app.post("/query")
115
  def query(request: QueryRequest):
116
  try:
117
+ logger.info(f"Received query: %s", request.question)
118
  result = chain.invoke({"query": request.question})
119
+ logger.info("Query processed successfully.")
120
+ return {"answer": result.get("result")}
121
  except Exception as e:
122
+ logger.error("Error processing query", exc_info=True)
123
+ raise HTTPException(status_code=500, detail="Internal server error.")