Turbiling commited on
Commit
7646bd1
Β·
verified Β·
1 Parent(s): 6af0db0

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +139 -0
app.py ADDED
@@ -0,0 +1,139 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import gradio as gr
3
+ import PyPDF2
4
+ import faiss
5
+ import numpy as np
6
+ from sentence_transformers import SentenceTransformer
7
+ from groq import Groq
8
+
9
+ # -------- Step 1: Set and Verify Groq API Key --------
10
+ os.environ["GROQ_API_KEY"] = "your-real-groq-api-key" # Replace this
11
+ api_key = os.getenv("GROQ_API_KEY")
12
+ if not api_key:
13
+ raise ValueError("❌ GROQ_API_KEY not found.")
14
+
15
+ client = Groq(api_key=api_key)
16
+
17
+ # -------- Step 2: Setup Model --------
18
+ model = SentenceTransformer("all-MiniLM-L6-v2")
19
+ faiss_index = None
20
+ chunks_list = []
21
+
22
+ # -------- Step 3: Extract Text from PDF --------
23
+ def extract_text_from_pdf(pdf_path, logs):
24
+ try:
25
+ text = ""
26
+ logs += "πŸ“– Step 1: Reading PDF...\n"
27
+ with open(pdf_path, 'rb') as file:
28
+ reader = PyPDF2.PdfReader(file)
29
+ for page in reader.pages:
30
+ page_text = page.extract_text()
31
+ if page_text:
32
+ text += page_text
33
+ if not text.strip():
34
+ raise ValueError("❌ No readable text found in PDF.")
35
+ logs += "βœ… Text extracted successfully.\n"
36
+ return text, logs
37
+ except Exception as e:
38
+ logs += f"❌ Error during PDF text extraction: {str(e)}\n"
39
+ return None, logs
40
+
41
+ # -------- Step 4: Chunking --------
42
+ def create_chunks(text, chunk_size, logs):
43
+ try:
44
+ logs += "🧩 Step 2: Creating text chunks...\n"
45
+ words = text.split()
46
+ chunks = [' '.join(words[i:i+chunk_size]) for i in range(0, len(words), chunk_size)]
47
+ logs += f"βœ… {len(chunks)} chunks created.\n"
48
+ return chunks, logs
49
+ except Exception as e:
50
+ logs += f"❌ Error in chunking: {str(e)}\n"
51
+ return None, logs
52
+
53
+ # -------- Step 5: Embeddings & Indexing --------
54
+ def embed_chunks(chunks, logs):
55
+ try:
56
+ logs += "πŸ“Š Step 3: Generating embeddings and creating FAISS index...\n"
57
+ embeddings = model.encode(chunks)
58
+ index = faiss.IndexFlatL2(embeddings.shape[1])
59
+ index.add(np.array(embeddings))
60
+ logs += "βœ… Embeddings & index created successfully.\n"
61
+ return index, chunks, logs
62
+ except Exception as e:
63
+ logs += f"❌ Error in embedding/indexing: {str(e)}\n"
64
+ return None, None, logs
65
+
66
+ # -------- Step 6: Process PDF --------
67
+ def process_pdf(file, chunk_size=200):
68
+ global faiss_index, chunks_list
69
+ logs = "πŸ“‚ File uploaded successfully.\n"
70
+ try:
71
+ text, logs = extract_text_from_pdf(file.name, logs)
72
+ if not text:
73
+ return logs
74
+
75
+ chunks, logs = create_chunks(text, chunk_size, logs)
76
+ if not chunks:
77
+ return logs
78
+
79
+ index, chunks, logs = embed_chunks(chunks, logs)
80
+ if not index:
81
+ return logs
82
+
83
+ faiss_index = index
84
+ chunks_list = chunks
85
+ logs += "πŸŽ‰ Step 4: PDF processed and ready for Q&A.\n"
86
+ return logs
87
+ except Exception as e:
88
+ logs += f"❌ Error during processing: {str(e)}\n"
89
+ return logs
90
+
91
+ # -------- Step 7: Ask Question --------
92
+ def answer_question(query):
93
+ logs = "πŸ€– Step 5: Processing your question...\n"
94
+ try:
95
+ if faiss_index is None:
96
+ return "❌ Please process a PDF first."
97
+
98
+ query_embedding = model.encode([query])
99
+ _, I = faiss_index.search(np.array(query_embedding), k=3)
100
+ relevant_chunks = [chunks_list[i] for i in I[0] if i < len(chunks_list)]
101
+
102
+ if not relevant_chunks:
103
+ return "❌ No relevant content found to answer your question."
104
+
105
+ context = "\n".join(relevant_chunks)
106
+ prompt = f"Answer the question based on the context below:\n\nContext:\n{context}\n\nQuestion: {query}"
107
+
108
+ logs += "🧠 Sending to Groq LLaMA3 model...\n"
109
+ response = client.chat.completions.create(
110
+ model="llama3-70b-8192",
111
+ messages=[{"role": "user", "content": prompt}]
112
+ )
113
+
114
+ answer = response.choices[0].message.content
115
+ logs += "βœ… Answer generated successfully.\n"
116
+ return f"{answer}\n\n{logs}"
117
+
118
+ except Exception as e:
119
+ logs += f"❌ Error during answering: {str(e)}\n"
120
+ return logs
121
+
122
+ # -------- Step 8: Gradio UI --------
123
+ with gr.Blocks() as demo:
124
+ gr.Markdown("## πŸ€– RAG PDF Q&A App with Groq + FAISS (Debug-Friendly)")
125
+
126
+ with gr.Row():
127
+ pdf_input = gr.File(label="πŸ“‚ Upload PDF", type="filepath")
128
+ process_btn = gr.Button("βš™οΈ Process PDF")
129
+ log_output = gr.Textbox(label="πŸ“ Logs", lines=20)
130
+
131
+ with gr.Row():
132
+ question_input = gr.Textbox(label="❓ Ask a Question")
133
+ answer_btn = gr.Button("πŸ’¬ Get Answer")
134
+ answer_output = gr.Textbox(label="πŸ“œ Answer + Logs", lines=20)
135
+
136
+ process_btn.click(fn=process_pdf, inputs=pdf_input, outputs=log_output)
137
+ answer_btn.click(fn=answer_question, inputs=question_input, outputs=answer_output)
138
+
139
+ demo.launch()