viraj commited on
Commit
f09e297
·
1 Parent(s): 05bc227

RAG app upload

Browse files
.env ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ OPENAI_API_KEY="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"
2
+ GROQ_API_KEY="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"
Dockerfile ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.10-slim
2
+
3
+ WORKDIR /app
4
+ COPY ./app /app
5
+
6
+ RUN pip install --upgrade pip
7
+ RUN pip install -r requirements.txt
8
+
9
+ EXPOSE 7860
10
+ CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "7860"]
files/1503253b-bb6d-40fa-a6df-77c6cd0c765a_Payments_.pdf ADDED
Binary file (57.5 kB). View file
 
files/1874da6d-0662-4e5e-9a6f-16801dd493ff_Payments_.pdf ADDED
Binary file (57.5 kB). View file
 
files/2701f754-a207-4e02-9cf1-9480aaabfafa_Payments_.pdf ADDED
Binary file (57.5 kB). View file
 
files/32d0ce30-093d-436a-8e0d-b12b251d1cf8_Payments_.pdf ADDED
Binary file (57.5 kB). View file
 
files/41975b82-5573-4f1d-9990-eea2364936f8_Payments_.pdf ADDED
Binary file (57.5 kB). View file
 
files/926c842a-bce7-47e8-a84a-5378677cad7e_Payments_.pdf ADDED
Binary file (57.5 kB). View file
 
files/a97aff56-f666-4e12-b6b2-3ea600b041ba_Payments_.pdf ADDED
Binary file (57.5 kB). View file
 
files/b0b0cd28-a5b7-4fa0-885b-4ed99a61ada9_Vehicle_Maintenance_SRS.pdf ADDED
Binary file (4.9 kB). View file
 
files/c0b8e4bb-914a-4475-aa6b-e4a67e4d8d87_Vehicle_Maintenance_SRS.pdf ADDED
Binary file (4.9 kB). View file
 
files/cf883c42-f8f5-4d36-a757-2946a8fb5d91_Payments_.pdf ADDED
Binary file (57.5 kB). View file
 
files/cfd14df9-21d4-49cf-9213-a644d3ebda41_Payments_.pdf ADDED
Binary file (57.5 kB). View file
 
files/ec91f7a5-e958-4b12-9dc5-05954ff579c8_Payments_.pdf ADDED
Binary file (57.5 kB). View file
 
files/ed4592f4-e79e-4c25-8355-e19fe09b51d9_Payments_.pdf ADDED
Binary file (57.5 kB). View file
 
files/f6ac9b57-252f-4b45-bef0-ffbd8cdc7d7e_Payments_.pdf ADDED
Binary file (57.5 kB). View file
 
main.py ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from rag_pipeline import process_file, answer_query
2
+ from pydantic import BaseModel
3
+
4
+ class QueryRequest(BaseModel):
5
+ file_id: str
6
+ question: str
7
+ page: int
8
+ explainLike5: bool = False
9
+
10
+ from fastapi import FastAPI, UploadFile, File
11
+ from fastapi.middleware.cors import CORSMiddleware
12
+ from dotenv import load_dotenv
13
+ from fastapi import Body
14
+ import uuid
15
+ import os
16
+ from langchain_chroma import Chroma
17
+ from langchain_huggingface import HuggingFaceEmbeddings
18
+ import re
19
+
20
+ load_dotenv()
21
+
22
+ CHROMA_DIR = "./chroma_db"
23
+ embedding_model = HuggingFaceEmbeddings(model_name="all-MiniLM-L6-v2")
24
+
25
+
26
+ app = FastAPI()
27
+ BASE_DIR = "files"
28
+ app.add_middleware(
29
+ CORSMiddleware,
30
+ allow_origins=["*"],
31
+ allow_methods=["*"],
32
+ allow_headers=["*"],
33
+ )
34
+ file_store = {}
35
+ @app.get("/test")
36
+ async def test():
37
+ return {"message": "hello world!"}
38
+
39
+ @app.post("/upload")
40
+ async def upload(file: UploadFile = File(...)):
41
+ content = await file.read()
42
+ file_id = str(uuid.uuid4())
43
+ safe_filename = file.filename.replace(" ", "_")
44
+ full_filename = f"{file_id}_{safe_filename}"
45
+ save_path = os.path.join(BASE_DIR, full_filename)
46
+ os.makedirs(BASE_DIR, exist_ok=True)
47
+ with open(save_path, "wb") as f:
48
+ f.write(content)
49
+ retriever = process_file(content, safe_filename, file_id)
50
+ file_store[file_id] = retriever
51
+ return {"message": "File processed", "file_id": file_id}
52
+
53
+ @app.post("/query")
54
+ async def query_endpoint(request = Body(...)):
55
+ file_id = request.get("file_id")
56
+ question = request.get("question")
57
+ selected_text = request.get("selectedText")
58
+ explain_like_5 = request.get("explainLike5", False)
59
+
60
+ if not file_id or not question:
61
+ return {"error": "Missing file_id or question"}
62
+
63
+ retriever_path = f"{CHROMA_DIR}/{file_id}"
64
+ # Load retriever from disk
65
+ if not os.path.exists(retriever_path):
66
+ return {"error": "Vectorstore for this file_id not found."}
67
+
68
+ vectorstore = Chroma(
69
+ embedding_function=embedding_model,
70
+ persist_directory=retriever_path
71
+ )
72
+ retriever = vectorstore.as_retriever(search_type="similarity", search_kwargs={"k": 4})
73
+ retrieved_docs = retriever.invoke(selected_text or question)
74
+ retrieved_context = "\n\n".join(
75
+ re.sub(r"\s+", " ", doc.page_content.strip()) for doc in retrieved_docs
76
+ )
77
+
78
+ combined_context = f"User selected this:\n\"{selected_text}\"\n\nRelated parts from the document:\n{retrieved_context}"
79
+ print("Combined context", combined_context)
80
+ answer = answer_query(question, combined_context, explain_like_5)
81
+ return {"answer": answer}
rag_pipeline.py ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import tempfile
2
+ from langchain_chroma import Chroma
3
+ from langchain_community.document_loaders import PyPDFLoader
4
+ from langchain.text_splitter import RecursiveCharacterTextSplitter
5
+ import os
6
+ from langchain_huggingface import HuggingFaceEmbeddings
7
+ import re
8
+ from groq import Groq
9
+ from dotenv import load_dotenv
10
+ load_dotenv()
11
+
12
+ client = Groq(api_key=os.environ["GROQ_API_KEY"])
13
+ CHROMA_DIR = "./chroma_db"
14
+ # Embedding model (free HuggingFace)
15
+ embedding_model = HuggingFaceEmbeddings(model_name="all-MiniLM-L6-v2")
16
+
17
+ def process_file(file_bytes, filename, file_id):
18
+ ext = filename.split('.')[-1].lower()
19
+ with tempfile.NamedTemporaryFile(delete=False, suffix=f".{ext}") as tmp:
20
+ tmp.write(file_bytes)
21
+ tmp_path = tmp.name
22
+
23
+ loader = PyPDFLoader(tmp_path) if ext == 'pdf' else None
24
+ docs = loader.load()
25
+
26
+ text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=100)
27
+ chunks = text_splitter.split_documents(docs)
28
+
29
+ vectorstore = Chroma.from_documents(
30
+ documents=chunks,
31
+ embedding=embedding_model,
32
+ persist_directory=f"{CHROMA_DIR}/{file_id}"
33
+ )
34
+ retriever = vectorstore.as_retriever(search_type="similarity", search_kwargs={"k": 4})
35
+ os.unlink(tmp_path)
36
+ return retriever
37
+
38
+
39
+ def answer_query(question, context, explain_like_5=False):
40
+ system_prompt = (
41
+ "You are a helpful assistant answering user queries based on provided document chunks.\n"
42
+ "Only use the given context. If the answer is not found, respond with 'I don't know.'"
43
+ )
44
+ if explain_like_5:
45
+ system_prompt += "\nExplain the answer in a simple way, like you're talking to a 5-year-old."
46
+
47
+ # Step 2: Send to LLM
48
+ print("context\======================================================================", context)
49
+ print("question =====================================================================", question)
50
+ response = client.chat.completions.create(
51
+ model="llama-3.3-70b-versatile",
52
+ messages=[
53
+ {"role": "system", "content": system_prompt},
54
+ {"role": "user", "content": f"Context:\n{context}\n\nQuestion:\n{question}"}
55
+ ]
56
+ )
57
+ return response.choices[0].message.content
requirments.txt ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ fastapi
2
+ uvicorn
3
+ python-multipart
4
+ pydantic
5
+ langchain
6
+ langchain-community
7
+ langchain-chroma
8
+ huggingface-hub
9
+ sentence-transformers
10
+ groq
11
+ python-dotenv