File size: 4,460 Bytes
da0b26a |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
# β
Install dependencies
# π Imports
import fitz # PyMuPDF
import requests
import gradio as gr
import tempfile
import os
import io
# π Enter your OpenRouter API key here
OPENROUTER_API_KEY = "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"
# Global variable to store the extracted text
pdf_text = ""
# π Extract text from PDF
def extract_text_from_pdf(file_obj):
global pdf_text
if file_obj is None:
return "Please upload a PDF file first."
try:
# Get the file path from the file object
# In Gradio, the file object has a name attribute that contains the path
file_path = file_obj.name
# Now open the file with PyMuPDF
doc = fitz.open(file_path)
text = ""
for page in doc:
text += page.get_text()
doc.close()
# Store the text for later use
pdf_text = text
# Return preview of the extracted text
preview = text[:500] + "..." if len(text) > 500 else text
return f"β
PDF uploaded and processed successfully. Preview:\n\n{preview}"
except Exception as e:
return f"β Error processing PDF: {str(e)}"
# π¬ Ask the open-source LLM (Mistral-7B via OpenRouter)
def ask_open_source_llm(question, model_choice="nvidia/llama-3.1-nemotron-nano-8b-v1:free"):
global pdf_text
if not pdf_text:
return "β οΈ Please upload a PDF document first."
# Limit text to prevent token overflow
limited_text = pdf_text[:3000] # First 3000 characters
# Create prompt based on question
if not question:
prompt = f"Summarize the following document:\n\n{limited_text}"
else:
prompt = f"The document says:\n\n{limited_text}\n\nNow answer this: {question}"
# Call the API
url = "https://openrouter.ai/api/v1/chat/completions"
headers = {
"Authorization": f"Bearer {OPENROUTER_API_KEY}",
"Content-Type": "application/json"
}
data = {
"model": model_choice,
"messages": [{"role": "user", "content": prompt}]
}
try:
response = requests.post(url, headers=headers, json=data)
if response.status_code == 200:
return response.json()["choices"][0]["message"]["content"]
else:
return f"β Error: {response.text}"
except Exception as e:
return f"β An error occurred: {str(e)}"
# Gradio app function
def process_query(pdf_file, question, model_choice):
# First extract text if a PDF is uploaded
if pdf_file is not None:
result = extract_text_from_pdf(pdf_file)
if result.startswith("β Error"):
return result
# Then process the question
if question:
return ask_open_source_llm(question, model_choice)
else:
return ask_open_source_llm("Please summarize this document.", model_choice)
# Create Gradio interface
with gr.Blocks(title="PDF Document Analysis") as app:
gr.Markdown("# π PDF Document Analysis with LLM")
gr.Markdown("Upload a PDF document and ask questions about its content.")
with gr.Row():
with gr.Column(scale=1):
pdf_input = gr.File(label="Upload PDF Document", file_types=[".pdf"])
model_choice = gr.Dropdown(
choices=[
"nvidia/llama-3.1-nemotron-nano-8b-v1:free",
"mistralai/mistral-7b-instruct-v0.1:free",
"meta-llama/llama-2-13b-chat:free"
],
label="LLM Model",
value="nvidia/llama-3.1-nemotron-nano-8b-v1:free"
)
question_input = gr.Textbox(label="Ask a question (or leave empty for summary)", lines=2)
submit_btn = gr.Button("Process", variant="primary")
with gr.Column(scale=2):
output = gr.Textbox(label="Response", lines=15)
# Set up event handlers
submit_btn.click(
fn=process_query,
inputs=[pdf_input, question_input, model_choice],
outputs=output
)
gr.Markdown("### π Notes")
gr.Markdown("- For large documents, only the first 3000 characters are analyzed")
gr.Markdown("- You can change the LLM model from the dropdown menu")
gr.Markdown("- Leave the question field empty to get a general summary")
# Launch the app
app.launch(debug=True, share=True) |