from fastapi import FastAPI from fastapi.responses import RedirectResponse import fitz # PyMuPDF import docx import openpyxl import pptx import io from PIL import Image import gradio as gr from transformers import pipeline # Models summarizer = pipeline("summarization", model="sshleifer/distilbart-cnn-12-6") image_captioner = pipeline("image-to-text", model="nlpconnect/vit-gpt2-image-captioning") app = FastAPI() # ------------------------- # Document Extraction Utils # ------------------------- def extract_text_from_pdf(file_bytes): text = "" with fitz.open(stream=file_bytes, filetype="pdf") as doc: for page in doc: text += page.get_text() return text def extract_text_from_docx(file_bytes): doc = docx.Document(io.BytesIO(file_bytes)) return "\n".join([para.text for para in doc.paragraphs if para.text.strip()]) def extract_text_from_pptx(file_bytes): text = [] prs = pptx.Presentation(io.BytesIO(file_bytes)) for slide in prs.slides: for shape in slide.shapes: if hasattr(shape, "text"): text.append(shape.text) return "\n".join(text) def extract_text_from_xlsx(file_bytes): wb = openpyxl.load_workbook(io.BytesIO(file_bytes)) text = [] for sheet in wb.sheetnames: ws = wb[sheet] for row in ws.iter_rows(values_only=True): line = " ".join(str(cell) for cell in row if cell) text.append(line) return "\n".join(text) def summarize_document(file): file_bytes = file.read() filename = getattr(file, "name", "").lower() if filename.endswith(".pdf"): text = extract_text_from_pdf(file_bytes) elif filename.endswith(".docx"): text = extract_text_from_docx(file_bytes) elif filename.endswith(".pptx"): text = extract_text_from_pptx(file_bytes) elif filename.endswith(".xlsx"): text = extract_text_from_xlsx(file_bytes) else: return "❌ Unsupported file format." if not text.strip(): return "❗ No extractable text found." try: summary = summarizer(text[:3000], max_length=150, min_length=30, do_sample=False) return f"📄 Summary:\n{summary[0]['summary_text']}" except Exception as e: return f"⚠️ Summarization error: {e}" def interpret_image(image): if image is None: return "No image uploaded." try: return f"🖼️ Caption:\n{image_captioner(image)[0]['generated_text']}" except Exception as e: return f"⚠️ Image captioning error: {e}" # ------------------------- # Gradio Interfaces # ------------------------- doc_summary = gr.Interface( fn=summarize_document, inputs=gr.File(label="Upload a Document"), outputs="text", title="📄 Document Summarizer" ) img_caption = gr.Interface( fn=interpret_image, inputs=gr.Image(type="pil", label="Upload an Image"), outputs="text", title="🖼️ Image Interpreter" ) # ------------------------- # Combine into Gradio + FastAPI # ------------------------- demo = gr.TabbedInterface([doc_summary, img_caption], ["Document Summary", "Image Captioning"]) app = gr.mount_gradio_app(app, demo, path="/") @app.get("/") def home(): return RedirectResponse(url="/")