PDF_Summarizer / app.py
TourLover's picture
Update app.py
f463c04 verified
raw
history blame
5 kB
import fitz # PyMuPDF
import pytesseract
from PIL import Image
import io
from fpdf import FPDF
import gradio as gr
import os
from pathlib import Path
from groq import Groq
from pdf2image import convert_from_path
import camelot
from fpdf import FPDF
import webbrowser
GROQ_API_KEY = "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"
client = Groq(api_key=GROQ_API_KEY)
def summarize_text(text, model="llama-3.1-70b-versatile"):
try:
chat_completion = client.chat.completions.create(
messages=[{"role": "user", "content": "Summarize this page in 15-20 lines under the heading of summary. You have to summarize, even if there are different, unlike topics on that page. (Kindly provide the response in proper paragraphing). However, if there is no text, then print Nothing to summarize. Additionally, after summarizing the text, enlist difficult terms up to 15, along with their single line meaning." + text}],
model=model,
)
return chat_completion.choices[0].message.content
except Exception as e:
print(f"[ERROR] Error in summarizing text: {e}")
return "Error in summarizing text."
# Function to extract text from PDF and generate a summarized PDF
def extract_text_and_summarize(filepath):
try:
if not os.path.exists(filepath):
print(f"[ERROR] File does not exist: {filepath}")
return "File does not exist."
doc = fitz.open(filepath)
print("[INFO] PDF opened successfully.")
# Initialize PDF to store summaries
pdf_summary = FPDF()
pdf_summary.set_auto_page_break(auto=True, margin=15)
# Process up to 50 pages
for page_num in range(min(doc.page_count, 50)):
data = "" # Initialize text variable for each page
print(f"[INFO] Extracting text from Page {page_num + 1}.")
page = doc.load_page(page_num)
# Extracting text
data += page.get_text()
print(f"[DEBUG] Text extracted from Page {page_num + 1}: {data[:100]}...") # Print first 100 characters
# Extracting images and performing OCR
image_list = page.get_images(full=True)
for img_index, img in enumerate(image_list):
try:
xref = img[0]
base_image = doc.extract_image(xref)
image_bytes = base_image["image"]
image_ext = base_image["ext"]
image = Image.open(io.BytesIO(image_bytes))
# Performing OCR on the image
ocr_text = pytesseract.image_to_string(image)
data += ocr_text
except Exception as e:
print(f"[ERROR] Error processing image on Page {page_num + 1}: {e}")
# Send the extracted text to LLM for summarization
summary = summarize_text(data)
# Add the summary to the output PDF
pdf_summary.add_page()
pdf_summary.set_font("Arial", size=12)
pdf_summary.multi_cell(0, 7, f"Summary of Page {page_num + 1}\n\n" + summary.encode('utf-8').decode('latin-1'))
# Save the output PDF
output_pdf_path = filepath.replace(".pdf", "_summary.pdf")
pdf_summary.output(output_pdf_path)
print("[INFO] Output PDF saved successfully.")
return output_pdf_path
except Exception as e:
print(f"[ERROR] Error processing the PDF: {e}")
return "Error processing the PDF."
# Function to handle file upload and initiate processing
def upload_file(filepath):
# Set status message to indicate processing
status_message = "Processing, Please wait..."
output_pdf_path = extract_text_and_summarize(filepath)
# Return status message and download button
return status_message, gr.update( visible=True, value=output_pdf_path)
def reset_interface(): # Function to reset the interface
return "", gr.update(visible=False)
# Create Gradio Interface
with gr.Blocks(css=".block {max-width: 800px; margin: auto; padding: 20px;}") as demo:
gr.Markdown("""
<h1 style='text-align: center; color: #4CAF50;'>PDF Summarizer</h1>
<p style='text-align: center; font-size: 1.2em; color: #666;'>Upload a PDF document and get a summarized version with page-by-page analysis and difficult term definitions for first 50 pages. Perfect for quick reviews and study aids!</p>
""")
with gr.Row():
u = gr.UploadButton("πŸ“ Upload your PDF", file_count="single")
d = gr.DownloadButton("⬇️ Download the summarized PDF", visible=False)
status = gr.Textbox(label="Status", placeholder="Status will be displayed here...", visible=True, interactive=False)
u.upload(upload_file, u, [status, d])
d.click(reset_interface, None, [status, d])
if __name__ == "__main__":
demo.launch()