Arabic-Ayat / main.py
Hammad712's picture
Update main.py
122de24 verified
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from langchain.chains import RetrievalQA
from langchain.prompts import PromptTemplate
from langchain_community.vectorstores import FAISS
from langchain_huggingface import HuggingFaceEmbeddings
from langchain_groq import ChatGroq
import zipfile
import os
app = FastAPI()
# === Startup config ===
class QueryRequest(BaseModel):
question: str
llm = None
retriever = None
chain = None
@app.on_event("startup")
def load_components():
global llm, retriever, chain
api_key = os.getenv('api_key')
# --- Load LLM ---
llm = ChatGroq(
model="meta-llama/llama-4-scout-17b-16e-instruct",
temperature=0,
max_tokens=1024,
api_key=api_key
)
# --- Load Embeddings ---
embeddings = HuggingFaceEmbeddings(
model_name="intfloat/multilingual-e5-large",
model_kwargs={"device": "cpu"},
encode_kwargs={"normalize_embeddings": True},
)
# --- Unzip Vectorstore if needed ---
zip_path = "faiss_index.zip"
extract_path = "faiss_index"
if not os.path.exists(extract_path):
with zipfile.ZipFile(zip_path, 'r') as z:
z.extractall(extract_path)
print("โœ… Unzipped FAISS index.")
# --- Load FAISS Vectorstore & create retriever ---
vectorstore = FAISS.load_local(
extract_path,
embeddings,
allow_dangerous_deserialization=True
)
retriever = vectorstore.as_retriever(search_kwargs={"k": 5})
print("โœ… FAISS index loaded.")
# --- Prepare prompt template ---
ayat_finder_prompt = '''
You are an Arabic Ayat Finder assistant.
Your goal is to provide an accurate and concise answer by extracting the exact Arabic verse (Ayah) from the provided retrieved context.
Your task is to output only the exact Ayah in Arabic as it appears in the context, along with its full reference details.
Instructions:
1. Locate the segment in the retrieved context that directly contains the requested Ayah.
2. Output only the Arabic text of the Ayah, without any additional commentary or translation.
3. Provide the complete reference alongside the Ayah, including:
- Surah number and name (Arabic and English)
- Ayah (verse) number
- Any other available metadata from the context (e.g., Juz number, Hizb, revelation order) if present.
4. If the exact Ayah cannot be found in the context, respond with "ู„ุง ุฃุนู„ู…".
5. Do not add, infer, or modify any content; strictly reproduce what exists in the context.
6. if ayat is multiple time give it multiple time in output
Retrieved context:
{context}
User's question:
{question}
Your response:
'''
prompt = PromptTemplate(
template=ayat_finder_prompt,
input_variables=["context", "question"]
)
# --- Assemble a stateless RetrievalQA chain (no memory) ---
chain = RetrievalQA.from_chain_type(
llm=llm,
chain_type="stuff",
retriever=retriever,
return_source_documents=False,
chain_type_kwargs={"prompt": prompt},
verbose=False,
)
@app.get("/")
def root():
return {"message": "Quran Ayat Finder API is up."}
@app.post("/query")
def query(request: QueryRequest):
try:
result = chain.invoke({"query": request.question})
return {"answer": result["result"]}
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))