Spaces:
Runtime error
Runtime error
| # app.py - v3.1: Manual PDF + Figure Upload with Downloadable Remixed Images (English Only, Nov 2025) | |
| import gradio as gr | |
| from gemini_nano import understand_image, chat, generate_image # Import from root | |
| from pypdf import PdfReader | |
| import os | |
| from dotenv import load_dotenv | |
| load_dotenv() | |
| pdf_context = "" # Global for PDF text extraction | |
| def extract_pdf_context(pdf_file): | |
| global pdf_context | |
| if pdf_file is None: | |
| pdf_context = "" | |
| return "No PDF uploaded. Upload optional PDF for context." | |
| try: | |
| reader = PdfReader(pdf_file) | |
| text = "" | |
| for page in reader.pages: # Read all pages | |
| text += page.extract_text() + "\n" | |
| pdf_context = text # No character limit | |
| return f"PDF context extracted ({len(pdf_context)} chars). Use for enhanced explanations." | |
| except Exception as e: | |
| return f"PDF extraction failed: {str(e)}" | |
| def analyze_and_remix(figure_img, prompt, use_context=False): | |
| if figure_img is None: | |
| return "Please upload a figure screenshot.", None, None | |
| try: | |
| # Base description | |
| desc_prompt = ["Describe this academic figure/equation/table in detail for first-year students."] | |
| if use_context: | |
| desc_prompt[0] += f"\nPaper context: {pdf_context}" | |
| desc_prompt.append(figure_img) | |
| desc = understand_image(figure_img) # Use updated function | |
| # Enhanced prompt for remix/annotation | |
| enhanced_prompt = prompt | |
| if "annotate" in prompt.lower() or "remix" in prompt.lower(): | |
| enhanced_prompt += ("\n\nGenerate a high-resolution, colorful, annotated or remixed image. " | |
| "Style: publication-quality scientific illustration, vibrant colors, clear labels for beginners. " | |
| "Include layman's explanations in callouts.") | |
| # Generate response + image | |
| full_prompt = [enhanced_prompt, figure_img] | |
| if use_context: | |
| full_prompt[0] += f"\nPaper context: {pdf_context}" | |
| response_text = chat(full_prompt) # Use updated chat function | |
| # Nano Banana Pro image generation (returns file path for download) | |
| img_file = generate_image(enhanced_prompt, figure_img) | |
| return desc, response_text, img_file | |
| except Exception as e: | |
| return f"Analysis failed: {str(e)}", None, None | |
| # UI - Simplified Manual Upload with Download | |
| with gr.Blocks(title="PaperSmith v3.1") as demo: | |
| gr.Markdown("# PaperSmith v3.1 β AI Figure Explainer & Remixer") | |
| gr.Markdown("Upload a PDF (optional, for context) + a figure screenshot β Enter request β Get description, explanation, and downloadable remixed image") | |
| with gr.Row(): | |
| pdf_input = gr.File(label="Upload full paper PDF (optional, for context)", file_types=[".pdf"]) | |
| figure_input = gr.Image(label="Upload figure screenshot from paper", type="pil") | |
| context_status = gr.Textbox(label="PDF Context Status", interactive=False) | |
| pdf_input.change(extract_pdf_context, pdf_input, context_status) | |
| with gr.Row(): | |
| prompt_input = gr.Textbox( | |
| placeholder="e.g. 'Annotate this equation with colorful boxes and layman's explanation'", | |
| label="Enter your request (or use examples below)" | |
| ) | |
| use_context = gr.Checkbox(label="Use PDF context for better accuracy", value=True) | |
| with gr.Row(): | |
| desc_output = gr.Textbox(label="Step 1: Figure Description", lines=4) | |
| explanation_output = gr.Textbox(label="Step 2: Detailed Explanation/Remix", lines=6) | |
| remixed_file = gr.File(label="Step 3: Download Annotated/Remixed Image (PNG)", visible=True) | |
| submit_btn = gr.Button("Analyze & Remix", variant="primary") | |
| submit_btn.click( | |
| analyze_and_remix, | |
| inputs=[figure_input, prompt_input, use_context], | |
| outputs=[desc_output, explanation_output, remixed_file] | |
| ) | |
| # Fixed Examples with proper chaining | |
| examples_component = gr.Examples( | |
| examples=[ | |
| ["Annotate this equation with colorful boxes and layman's explanation"], | |
| ["Remix this figure to make it more intuitive and high-definition"], | |
| ["Convert this table into a beautiful infographic with key insights"], | |
| ["Explain this attention visualization for first-year students"], | |
| ["Add colorful callouts to this heatmap showing what each color means"], | |
| ["Reproduce this chart with vibrant colors and simple labels for a presentation"], | |
| ["Annotate this transformer architecture diagram step-by-step"], | |
| ["Turn this probability experiment into an interactive visual story"], | |
| ["Highlight key trends in this line plot with arrows and beginner notes"], | |
| ["Create a simplified version of this neural network diagram for slides"] | |
| ], | |
| inputs=[prompt_input] | |
| ) | |
| # Chain .then() to load_input_event: Auto-populate prompt on example click | |
| examples_component.load_input_event.then( | |
| lambda ex: gr.update(value=ex[0]), # Populate textbox with selected example | |
| outputs=prompt_input | |
| ) | |
| gr.Markdown("**Powered by Gemini 2.5 Flash + Gemini 2.5 Flash Image (Nano Banana Pro)** | Group 23 β Generative AI in Creative Industries") | |
| if __name__ == "__main__": | |
| demo.launch() |