Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
|
@@ -69,125 +69,128 @@ app = gr.mount_gradio_app(app, demo, path="/")
|
|
| 69 |
def root():
|
| 70 |
return RedirectResponse(url="/")
|
| 71 |
"""
|
| 72 |
-
from fastapi import FastAPI
|
| 73 |
-
from fastapi.responses import RedirectResponse
|
| 74 |
import gradio as gr
|
| 75 |
-
import
|
| 76 |
-
|
| 77 |
-
import
|
| 78 |
-
import
|
| 79 |
-
import
|
| 80 |
-
import
|
| 81 |
-
import openpyxl
|
| 82 |
-
from pptx import Presentation
|
| 83 |
-
from transformers import pipeline
|
| 84 |
from deep_translator import GoogleTranslator
|
| 85 |
-
import
|
| 86 |
-
import
|
|
|
|
| 87 |
|
|
|
|
| 88 |
app = FastAPI()
|
| 89 |
|
| 90 |
-
|
| 91 |
-
|
| 92 |
-
|
| 93 |
-
#
|
| 94 |
|
|
|
|
| 95 |
def extract_text_from_pdf(pdf_file):
|
| 96 |
-
|
| 97 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 98 |
|
| 99 |
def extract_text_from_docx(docx_file):
|
|
|
|
| 100 |
doc = docx.Document(docx_file)
|
| 101 |
-
return "\n".join([
|
| 102 |
|
| 103 |
def extract_text_from_pptx(pptx_file):
|
| 104 |
-
|
| 105 |
text = []
|
| 106 |
-
|
| 107 |
-
|
| 108 |
-
|
| 109 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 110 |
return "\n".join(text)
|
| 111 |
|
| 112 |
def extract_text_from_xlsx(xlsx_file):
|
| 113 |
-
|
| 114 |
text = []
|
| 115 |
-
|
| 116 |
-
|
| 117 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 118 |
return "\n".join(text)
|
| 119 |
|
| 120 |
-
def
|
| 121 |
-
|
| 122 |
-
|
| 123 |
-
|
| 124 |
-
elif ext == ".docx":
|
| 125 |
-
return extract_text_from_docx(file)
|
| 126 |
-
elif ext == ".pptx":
|
| 127 |
-
return extract_text_from_pptx(file)
|
| 128 |
-
elif ext == ".xlsx":
|
| 129 |
-
return extract_text_from_xlsx(file)
|
| 130 |
-
else:
|
| 131 |
-
return "Unsupported file type"
|
| 132 |
-
|
| 133 |
-
def answer_question_from_doc(file, question, translate_to="en"):
|
| 134 |
-
context = extract_text(file)
|
| 135 |
-
result = qa_pipeline(question=question, context=context)
|
| 136 |
-
translated = GoogleTranslator(source='auto', target=translate_to).translate(result["answer"])
|
| 137 |
-
return {
|
| 138 |
-
"answer": translated,
|
| 139 |
-
"score": result["score"],
|
| 140 |
-
"original": result["answer"]
|
| 141 |
-
}
|
| 142 |
-
|
| 143 |
-
def answer_question_from_image(image, question, translate_to="en"):
|
| 144 |
-
img_text = pytesseract.image_to_string(image)
|
| 145 |
-
if not img_text.strip():
|
| 146 |
-
img_text = "\n".join([line[1] for line in reader.readtext(image)])
|
| 147 |
-
result = qa_pipeline(question=question, context=img_text)
|
| 148 |
-
translated = GoogleTranslator(source='auto', target=translate_to).translate(result["answer"])
|
| 149 |
-
return {
|
| 150 |
-
"answer": translated,
|
| 151 |
-
"score": result["score"],
|
| 152 |
-
"original": result["answer"]
|
| 153 |
-
}
|
| 154 |
|
| 155 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 156 |
|
| 157 |
-
|
| 158 |
-
|
| 159 |
-
inputs=[
|
| 160 |
-
gr.File(label="Upload Document (PDF, DOCX, PPTX, XLSX)"),
|
| 161 |
-
gr.Textbox(label="Ask a Question"),
|
| 162 |
-
gr.Textbox(label="Translate Answer To (e.g., en, fr, ar)", value="en")
|
| 163 |
-
],
|
| 164 |
-
outputs=[
|
| 165 |
-
gr.Textbox(label="Translated Answer"),
|
| 166 |
-
gr.Number(label="Confidence Score"),
|
| 167 |
-
gr.Textbox(label="Original Answer")
|
| 168 |
-
],
|
| 169 |
-
title="📄 Document QA + Translation + Export"
|
| 170 |
-
)
|
| 171 |
|
| 172 |
-
|
| 173 |
-
|
| 174 |
-
|
| 175 |
-
gr.Image(label="Upload Image"),
|
| 176 |
-
gr.Textbox(label="Ask a Question"),
|
| 177 |
-
gr.Textbox(label="Translate Answer To (e.g., en, fr, ar)", value="en")
|
| 178 |
-
],
|
| 179 |
-
outputs=[
|
| 180 |
-
gr.Textbox(label="Translated Answer"),
|
| 181 |
-
gr.Number(label="Confidence Score"),
|
| 182 |
-
gr.Textbox(label="Original Answer")
|
| 183 |
-
],
|
| 184 |
-
title="🖼️ Image QA + OCR + Translation + Export"
|
| 185 |
-
)
|
| 186 |
|
| 187 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 188 |
demo = gr.TabbedInterface([doc_interface, img_interface], ["Document QA", "Image QA"])
|
| 189 |
app = gr.mount_gradio_app(app, demo, path="/")
|
| 190 |
|
| 191 |
@app.get("/")
|
| 192 |
-
def
|
| 193 |
return RedirectResponse(url="/")
|
|
|
|
| 69 |
def root():
|
| 70 |
return RedirectResponse(url="/")
|
| 71 |
"""
|
|
|
|
|
|
|
| 72 |
import gradio as gr
|
| 73 |
+
import fitz # PyMuPDF for PDFs
|
| 74 |
+
import easyocr # OCR for images
|
| 75 |
+
import openpyxl # XLSX processing
|
| 76 |
+
import pptx # PPTX processing
|
| 77 |
+
import docx # DOCX processing
|
| 78 |
+
import json # Exporting results
|
|
|
|
|
|
|
|
|
|
| 79 |
from deep_translator import GoogleTranslator
|
| 80 |
+
from transformers import pipeline
|
| 81 |
+
from fastapi import FastAPI
|
| 82 |
+
from starlette.responses import RedirectResponse
|
| 83 |
|
| 84 |
+
# Initialize FastAPI app
|
| 85 |
app = FastAPI()
|
| 86 |
|
| 87 |
+
# Initialize AI Models
|
| 88 |
+
qa_model = pipeline("text-generation", model="TinyLlama/TinyLlama-1.1B-Chat-v1.0")
|
| 89 |
+
image_captioning = pipeline("image-to-text", model="nlpconnect/vit-gpt2-image-captioning")
|
| 90 |
+
reader = easyocr.Reader(['en', 'fr']) # EasyOCR for image text extraction (English & French)
|
| 91 |
|
| 92 |
+
# ---- TEXT EXTRACTION FUNCTIONS ----
|
| 93 |
def extract_text_from_pdf(pdf_file):
|
| 94 |
+
"""Extract text from a PDF file."""
|
| 95 |
+
text = []
|
| 96 |
+
try:
|
| 97 |
+
with fitz.open(pdf_file) as doc:
|
| 98 |
+
for page in doc:
|
| 99 |
+
text.append(page.get_text("text"))
|
| 100 |
+
except Exception as e:
|
| 101 |
+
return f"Error reading PDF: {e}"
|
| 102 |
+
return "\n".join(text)
|
| 103 |
|
| 104 |
def extract_text_from_docx(docx_file):
|
| 105 |
+
"""Extract text from a DOCX file."""
|
| 106 |
doc = docx.Document(docx_file)
|
| 107 |
+
return "\n".join([p.text for p in doc.paragraphs if p.text.strip()])
|
| 108 |
|
| 109 |
def extract_text_from_pptx(pptx_file):
|
| 110 |
+
"""Extract text from a PPTX file."""
|
| 111 |
text = []
|
| 112 |
+
try:
|
| 113 |
+
presentation = pptx.Presentation(pptx_file)
|
| 114 |
+
for slide in presentation.slides:
|
| 115 |
+
for shape in slide.shapes:
|
| 116 |
+
if hasattr(shape, "text"):
|
| 117 |
+
text.append(shape.text)
|
| 118 |
+
except Exception as e:
|
| 119 |
+
return f"Error reading PPTX: {e}"
|
| 120 |
return "\n".join(text)
|
| 121 |
|
| 122 |
def extract_text_from_xlsx(xlsx_file):
|
| 123 |
+
"""Extract text from an XLSX file."""
|
| 124 |
text = []
|
| 125 |
+
try:
|
| 126 |
+
wb = openpyxl.load_workbook(xlsx_file)
|
| 127 |
+
for sheet in wb.sheetnames:
|
| 128 |
+
ws = wb[sheet]
|
| 129 |
+
for row in ws.iter_rows(values_only=True):
|
| 130 |
+
text.append(" ".join(str(cell) for cell in row if cell))
|
| 131 |
+
except Exception as e:
|
| 132 |
+
return f"Error reading XLSX: {e}"
|
| 133 |
return "\n".join(text)
|
| 134 |
|
| 135 |
+
def extract_text_from_image(image_path):
|
| 136 |
+
"""Extract text from an image using EasyOCR."""
|
| 137 |
+
result = reader.readtext(image_path, detail=0)
|
| 138 |
+
return " ".join(result) # Return text as a single string
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 139 |
|
| 140 |
+
# ---- MAIN PROCESSING FUNCTIONS ----
|
| 141 |
+
def answer_question_from_doc(file, question):
|
| 142 |
+
"""Process document and answer a question based on its content."""
|
| 143 |
+
ext = file.name.split(".")[-1].lower()
|
| 144 |
+
|
| 145 |
+
if ext == "pdf":
|
| 146 |
+
context = extract_text_from_pdf(file.name)
|
| 147 |
+
elif ext == "docx":
|
| 148 |
+
context = extract_text_from_docx(file.name)
|
| 149 |
+
elif ext == "pptx":
|
| 150 |
+
context = extract_text_from_pptx(file.name)
|
| 151 |
+
elif ext == "xlsx":
|
| 152 |
+
context = extract_text_from_xlsx(file.name)
|
| 153 |
+
else:
|
| 154 |
+
return "Unsupported file format."
|
| 155 |
|
| 156 |
+
if not context.strip():
|
| 157 |
+
return "No text found in the document."
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 158 |
|
| 159 |
+
# Generate answer using AI
|
| 160 |
+
answer = qa_model(question + " " + context, max_length=100)[0]["generated_text"]
|
| 161 |
+
return answer
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 162 |
|
| 163 |
+
def answer_question_from_image(image, question):
|
| 164 |
+
"""Process an image, extract text, and answer a question."""
|
| 165 |
+
img_text = extract_text_from_image(image)
|
| 166 |
+
if not img_text.strip():
|
| 167 |
+
return "No readable text found in the image."
|
| 168 |
+
|
| 169 |
+
# Generate answer using AI
|
| 170 |
+
answer = qa_model(question + " " + img_text, max_length=100)[0]["generated_text"]
|
| 171 |
+
return answer
|
| 172 |
+
|
| 173 |
+
# ---- GRADIO INTERFACES ----
|
| 174 |
+
with gr.Blocks() as doc_interface:
|
| 175 |
+
gr.Markdown("## Document Question Answering")
|
| 176 |
+
file_input = gr.File(label="Upload DOCX, PPTX, XLSX, or PDF")
|
| 177 |
+
question_input = gr.Textbox(label="Ask a question")
|
| 178 |
+
answer_output = gr.Textbox(label="Answer")
|
| 179 |
+
file_submit = gr.Button("Get Answer")
|
| 180 |
+
file_submit.click(answer_question_from_doc, inputs=[file_input, question_input], outputs=answer_output)
|
| 181 |
+
|
| 182 |
+
with gr.Blocks() as img_interface:
|
| 183 |
+
gr.Markdown("## Image Question Answering")
|
| 184 |
+
image_input = gr.Image(label="Upload an Image")
|
| 185 |
+
img_question_input = gr.Textbox(label="Ask a question")
|
| 186 |
+
img_answer_output = gr.Textbox(label="Answer")
|
| 187 |
+
image_submit = gr.Button("Get Answer")
|
| 188 |
+
image_submit.click(answer_question_from_image, inputs=[image_input, img_question_input], outputs=img_answer_output)
|
| 189 |
+
|
| 190 |
+
# ---- MOUNT GRADIO APP ----
|
| 191 |
demo = gr.TabbedInterface([doc_interface, img_interface], ["Document QA", "Image QA"])
|
| 192 |
app = gr.mount_gradio_app(app, demo, path="/")
|
| 193 |
|
| 194 |
@app.get("/")
|
| 195 |
+
def home():
|
| 196 |
return RedirectResponse(url="/")
|