ikraamkb commited on
Commit
4c11732
Β·
verified Β·
1 Parent(s): 5c0f80c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +53 -179
app.py CHANGED
@@ -4,41 +4,29 @@ from tika import parser # Apache Tika for document parsing
4
  import openpyxl
5
  from pptx import Presentation
6
  import torch
7
- from torchvision import transforms
8
- from torchvision.models.detection import fasterrcnn_resnet50_fpn
9
  from PIL import Image
10
  from transformers import pipeline
11
  import gradio as gr
12
- from fastapi.responses import RedirectResponse
13
  import numpy as np
 
14
 
15
- # Initialize FastAPI
16
- print("πŸš€ FastAPI server is starting...")
17
  app = FastAPI()
18
 
19
- # Load AI Model for Question Answering (DeepSeek-V2-Chat)
20
- from transformers import AutoModelForCausalLM, AutoTokenizer
21
-
22
- # Preload Hugging Face model
23
  print(f"πŸ”„ Loading models")
24
- qa_pipeline = pipeline("text-generation", model="TinyLlama/TinyLlama-1.1B-Chat-v1.0", device=-1)
25
 
26
- # Load Pretrained Object Detection Model (Torchvision)
27
- from torchvision.models.detection import FasterRCNN_ResNet50_FPN_Weights
28
- weights = FasterRCNN_ResNet50_FPN_Weights.DEFAULT
29
- model = fasterrcnn_resnet50_fpn(weights=weights)
30
- model.eval()
31
 
32
- # Image Transformations
33
- transform = transforms.Compose([
34
- transforms.ToTensor()
35
- ])
36
 
37
  # Allowed File Extensions
38
  ALLOWED_EXTENSIONS = {"pdf", "docx", "pptx", "xlsx"}
39
 
40
  def validate_file_type(file):
41
- ext = file.name.split(".")[-1].lower()
42
  print(f"πŸ” Validating file type: {ext}")
43
  if ext not in ALLOWED_EXTENSIONS:
44
  return f"❌ Unsupported file format: {ext}"
@@ -52,209 +40,95 @@ def truncate_text(text, max_tokens=450):
52
  return truncated
53
 
54
  # Document Text Extraction Functions
55
- def extract_text_from_pdf(pdf_file):
56
  try:
57
  print("πŸ“„ Extracting text from PDF...")
58
- doc = fitz.open(pdf_file)
59
  text = "\n".join([page.get_text("text") for page in doc])
60
- print("βœ… PDF text extraction completed.")
61
  return text if text else "⚠️ No text found."
62
  except Exception as e:
63
  return f"❌ Error reading PDF: {str(e)}"
64
 
65
- def extract_text_with_tika(file):
66
  try:
67
  print("πŸ“ Extracting text with Tika...")
68
- parsed = parser.from_buffer(file)
69
- print("βœ… Tika text extraction completed.")
70
  return parsed.get("content", "⚠️ No text found.").strip()
71
  except Exception as e:
72
  return f"❌ Error reading document: {str(e)}"
73
 
74
- def extract_text_from_pptx(pptx_file):
75
- try:
76
- print("πŸ“Š Extracting text from PPTX...")
77
- ppt = Presentation(pptx_file)
78
- text = []
79
- for slide in ppt.slides:
80
- for shape in slide.shapes:
81
- if hasattr(shape, "text"):
82
- text.append(shape.text)
83
- print("βœ… PPTX text extraction completed.")
84
- return "\n".join(text) if text else "⚠️ No text found."
85
- except Exception as e:
86
- return f"❌ Error reading PPTX: {str(e)}"
87
-
88
- def extract_text_from_excel(excel_file):
89
  try:
90
  print("πŸ“Š Extracting text from Excel...")
91
- wb = openpyxl.load_workbook(excel_file, read_only=True)
92
  text = []
93
  for sheet in wb.worksheets:
94
  for row in sheet.iter_rows(values_only=True):
95
  text.append(" ".join(map(str, row)))
96
- print("βœ… Excel text extraction completed.")
97
  return "\n".join(text) if text else "⚠️ No text found."
98
  except Exception as e:
99
  return f"❌ Error reading Excel: {str(e)}"
100
 
101
- def answer_question_from_document(file, question):
102
  print("πŸ“‚ Processing document for QA...")
103
  validation_error = validate_file_type(file)
104
  if validation_error:
105
  return validation_error
106
- file_ext = file.name.split(".")[-1].lower()
 
 
 
107
  if file_ext == "pdf":
108
- text = extract_text_from_pdf(file)
109
  elif file_ext in ["docx", "pptx"]:
110
- text = extract_text_with_tika(file)
111
  elif file_ext == "xlsx":
112
- text = extract_text_from_excel(file)
113
  else:
114
  return "❌ Unsupported file format!"
 
115
  if not text:
116
  return "⚠️ No text extracted from the document."
 
117
  truncated_text = truncate_text(text)
118
  print("πŸ€– Generating response...")
119
- response = qa_pipeline(f"Question: {question}\nContext: {truncated_text}")
120
- print("βœ… AI response generated.")
121
  return response[0]["generated_text"]
122
 
123
- print("βœ… Models loaded successfully.")
124
-
125
- doc_interface = gr.Interface(fn=answer_question_from_document, inputs=[gr.File(), gr.Textbox()], outputs="text")
126
-
127
- demo = gr.TabbedInterface([doc_interface], ["Document QA"])
128
- app = gr.mount_gradio_app(app, demo, path="/")
129
-
130
- @app.get("/")
131
- def home():
132
- return RedirectResponse(url="/")
133
-
134
-
135
-
136
- """import gradio as gr
137
- import pandas as pd
138
- import matplotlib.pyplot as plt
139
- import seaborn as sns
140
- from fastapi import FastAPI
141
- from transformers import pipeline
142
- from fastapi.responses import RedirectResponse
143
- import io
144
- import ast
145
- from PIL import Image
146
- import re
147
-
148
- # βœ… Load AI models
149
- print("πŸš€ Initializing application...")
150
- table_analyzer = pipeline("question-answering", model="deepset/tinyroberta-squad2", device=-1)
151
- code_generator = pipeline("text-generation", model="distilgpt2", device=-1)
152
- print("βœ… AI models loaded successfully!")
153
-
154
- # βœ… Initialize FastAPI
155
- app = FastAPI()
156
-
157
- def generate_visualization(excel_file, viz_type, user_request):
158
- Generates Python visualization code and insights based on user requests and Excel data.
159
  try:
160
- print("πŸ“‚ Loading Excel file...")
161
- df = pd.read_excel(excel_file)
162
- print("βœ… File loaded successfully! Columns:", df.columns)
163
-
164
- # Convert date columns
165
- for col in df.select_dtypes(include=["object", "datetime64"]):
166
- try:
167
- df[col] = pd.to_datetime(df[col], errors='coerce').dt.strftime('%Y-%m-%d %H:%M:%S')
168
- except Exception:
169
- pass
170
-
171
- df = df.fillna(0) # Fill NaN values
172
-
173
- formatted_table = [{col: str(value) for col, value in row.items()} for row in df.to_dict(orient="records")]
174
- print(f"πŸ“Š Formatted table: {formatted_table[:5]}")
175
- print(f"πŸ” User request: {user_request}")
176
-
177
- if not isinstance(user_request, str):
178
- raise ValueError("User request must be a string")
179
-
180
- print("🧠 Sending data to TAPAS model for analysis...")
181
- table_answer = table_analyzer({"table": formatted_table, "query": user_request})
182
- print("βœ… Table analysis completed!")
183
-
184
- # βœ… AI-generated code
185
- prompt = f Generate clean and executable Python code to visualize the following dataset:
186
- Columns: {list(df.columns)}
187
- Visualization type: {viz_type}
188
- User request: {user_request}
189
- Use the provided DataFrame 'df' without reloading it.
190
- Ensure 'plt.show()' is at the end.
191
 
 
 
192
 
193
- print("πŸ€– Sending request to AI code generator...")
194
- generated_code = code_generator(prompt, max_length=200)[0]['generated_text']
195
- print("πŸ“ AI-generated code:")
196
- print(generated_code)
197
-
198
- # βœ… Validate generated code
199
- valid_syntax = re.match(r".*plt\.show\(\).*", generated_code, re.DOTALL)
200
- if not valid_syntax:
201
- print("⚠️ AI code generation failed! Using fallback visualization...")
202
- return generated_code, "Error: The AI did not generate a valid Matplotlib script."
203
-
204
- try:
205
- ast.parse(generated_code) # Syntax validation
206
- except SyntaxError as e:
207
- return generated_code, f"Syntax error: {e}"
208
-
209
- # βœ… Execute AI-generated code
210
- try:
211
- print("⚑ Executing AI-generated code...")
212
- exec_globals = {"plt": plt, "sns": sns, "pd": pd, "df": df.copy(), "io": io}
213
- exec(generated_code, exec_globals)
214
-
215
- fig = plt.gcf()
216
- img_buf = io.BytesIO()
217
- fig.savefig(img_buf, format='png')
218
- img_buf.seek(0)
219
- plt.close(fig)
220
- except Exception as e:
221
- print(f"❌ Error executing AI-generated code: {str(e)}")
222
- return generated_code, f"Error executing visualization: {str(e)}"
223
-
224
- img = Image.open(img_buf)
225
- return generated_code, img
226
 
 
227
  except Exception as e:
228
- print(f"❌ An error occurred: {str(e)}")
229
- return f"Error: {str(e)}", "Table analysis failed."
 
 
 
 
 
 
 
230
 
231
- # βœ… Gradio UI setup
232
- print("πŸ› οΈ Setting up Gradio interface...")
233
- gradio_ui = gr.Interface(
234
- fn=generate_visualization,
235
- inputs=[
236
- gr.File(label="Upload Excel File"),
237
- gr.Radio([
238
- "Bar Chart", "Line Chart", "Scatter Plot", "Histogram",
239
- "Boxplot", "Heatmap", "Pie Chart", "Area Chart", "Bubble Chart", "Violin Plot"
240
- ], label="Select Visualization Type"),
241
- gr.Textbox(label="Enter visualization request (e.g., 'Sales trend over time')")
242
- ],
243
- outputs=[
244
- gr.Code(label="Generated Python Code"),
245
- gr.Image(label="Visualization Result")
246
- ],
247
- title="AI-Powered Data Visualization πŸ“Š",
248
- description="Upload an Excel file, choose your visualization type, and ask a question about your data!"
249
  )
250
- print("βœ… Gradio interface configured successfully!")
251
 
252
- # βœ… Mount Gradio app
253
- print("πŸ”— Mounting Gradio interface on FastAPI...")
254
- app = gr.mount_gradio_app(app, gradio_ui, path="/")
255
- print("βœ… Gradio interface mounted successfully!")
256
 
257
- @app.get("/")
258
- def home():
259
- print("🏠 Redirecting to UI...")
260
- return RedirectResponse(url="/")"""
 
4
  import openpyxl
5
  from pptx import Presentation
6
  import torch
 
 
7
  from PIL import Image
8
  from transformers import pipeline
9
  import gradio as gr
 
10
  import numpy as np
11
+ import easyocr
12
 
13
+ # Initialize FastAPI (not needed for HF Spaces, but kept for flexibility)
 
14
  app = FastAPI()
15
 
 
 
 
 
16
  print(f"πŸ”„ Loading models")
 
17
 
18
+ doc_qa_pipeline = pipeline("text2text-generation", model="TinyLlama/TinyLlama-1.1B-Chat-v1.0", device=-1)
19
+ image_captioning_pipeline = pipeline("image-to-text", model="nlpconnect/vit-gpt2-image-captioning")
20
+ print("βœ… Models loaded")
 
 
21
 
22
+ # Initialize OCR Model (CPU Mode)
23
+ reader = easyocr.Reader(["en"], gpu=False)
 
 
24
 
25
  # Allowed File Extensions
26
  ALLOWED_EXTENSIONS = {"pdf", "docx", "pptx", "xlsx"}
27
 
28
  def validate_file_type(file):
29
+ ext = file.filename.split(".")[-1].lower()
30
  print(f"πŸ” Validating file type: {ext}")
31
  if ext not in ALLOWED_EXTENSIONS:
32
  return f"❌ Unsupported file format: {ext}"
 
40
  return truncated
41
 
42
  # Document Text Extraction Functions
43
+ def extract_text_from_pdf(pdf_bytes):
44
  try:
45
  print("πŸ“„ Extracting text from PDF...")
46
+ doc = fitz.open(stream=pdf_bytes, filetype="pdf")
47
  text = "\n".join([page.get_text("text") for page in doc])
 
48
  return text if text else "⚠️ No text found."
49
  except Exception as e:
50
  return f"❌ Error reading PDF: {str(e)}"
51
 
52
+ def extract_text_with_tika(file_bytes):
53
  try:
54
  print("πŸ“ Extracting text with Tika...")
55
+ parsed = parser.from_buffer(file_bytes)
 
56
  return parsed.get("content", "⚠️ No text found.").strip()
57
  except Exception as e:
58
  return f"❌ Error reading document: {str(e)}"
59
 
60
+ def extract_text_from_excel(excel_bytes):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
  try:
62
  print("πŸ“Š Extracting text from Excel...")
63
+ wb = openpyxl.load_workbook(excel_bytes, read_only=True)
64
  text = []
65
  for sheet in wb.worksheets:
66
  for row in sheet.iter_rows(values_only=True):
67
  text.append(" ".join(map(str, row)))
 
68
  return "\n".join(text) if text else "⚠️ No text found."
69
  except Exception as e:
70
  return f"❌ Error reading Excel: {str(e)}"
71
 
72
+ def answer_question_from_document(file: UploadFile, question: str):
73
  print("πŸ“‚ Processing document for QA...")
74
  validation_error = validate_file_type(file)
75
  if validation_error:
76
  return validation_error
77
+
78
+ file_ext = file.filename.split(".")[-1].lower()
79
+ file_bytes = file.file.read()
80
+
81
  if file_ext == "pdf":
82
+ text = extract_text_from_pdf(file_bytes)
83
  elif file_ext in ["docx", "pptx"]:
84
+ text = extract_text_with_tika(file_bytes)
85
  elif file_ext == "xlsx":
86
+ text = extract_text_from_excel(file_bytes)
87
  else:
88
  return "❌ Unsupported file format!"
89
+
90
  if not text:
91
  return "⚠️ No text extracted from the document."
92
+
93
  truncated_text = truncate_text(text)
94
  print("πŸ€– Generating response...")
95
+ response = doc_qa_pipeline(f"Question: {question}\nContext: {truncated_text}")
96
+
97
  return response[0]["generated_text"]
98
 
99
+ def answer_question_from_image(image, question):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
100
  try:
101
+ print("πŸ–ΌοΈ Processing image for QA...")
102
+ if isinstance(image, np.ndarray): # If it's a NumPy array from Gradio
103
+ image = Image.fromarray(image) # Convert to PIL Image
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
 
105
+ print("πŸ–ΌοΈ Generating caption for image...")
106
+ caption = image_captioning_pipeline(image)[0]['generated_text']
107
 
108
+ print("πŸ€– Answering question based on caption...")
109
+ response = doc_qa_pipeline(f"Question: {question}\nContext: {caption}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
110
 
111
+ return response[0]["generated_text"]
112
  except Exception as e:
113
+ return f"❌ Error processing image: {str(e)}"
114
+
115
+ # Gradio UI for Document & Image QA
116
+ doc_interface = gr.Interface(
117
+ fn=answer_question_from_document,
118
+ inputs=[gr.File(label="πŸ“‚ Upload Document"), gr.Textbox(label="πŸ’¬ Ask a Question")],
119
+ outputs="text",
120
+ title="πŸ“„ AI Document Question Answering"
121
+ )
122
 
123
+ img_interface = gr.Interface(
124
+ fn=answer_question_from_image,
125
+ inputs=[gr.Image(label="πŸ–ΌοΈ Upload Image"), gr.Textbox(label="πŸ’¬ Ask a Question")],
126
+ outputs="text",
127
+ title="πŸ–ΌοΈ AI Image Question Answering"
 
 
 
 
 
 
 
 
 
 
 
 
 
128
  )
 
129
 
130
+ # Launch Gradio
131
+ app = gr.TabbedInterface([doc_interface, img_interface], ["πŸ“„ Document QA", "πŸ–ΌοΈ Image QA"])
 
 
132
 
133
+ if __name__ == "__main__":
134
+ app.launch(share=True) # For Hugging Face Spaces