layout_late / app.py
deepkansara-123's picture
Update app.py
e4e727a verified
# import gradio as gr
# print("GRADIO VERSION:", gr.__version__)
# import json
# import os
# import tempfile
# from pathlib import Path
# # NOTE: You must ensure that 'working_yolo_pipeline.py' exists
# # and defines the following items correctly:
# from working_yolo_pipeline import run_document_pipeline, DEFAULT_LAYOUTLMV3_MODEL_PATH, WEIGHTS_PATH
# # Since I don't have this file, I am assuming the imports are correct.
# # Define placeholders for assumed constants if the pipeline file isn't present
# # You should replace these with your actual definitions if they are missing
# try:
# from working_yolo_pipeline import run_document_pipeline, DEFAULT_LAYOUTLMV3_MODEL_PATH, WEIGHTS_PATH
# except ImportError:
# print("Warning: 'working_yolo_pipeline.py' not found. Using dummy paths.")
# def run_document_pipeline(*args):
# return {"error": "Placeholder pipeline function called."}
# DEFAULT_LAYOUTLMV3_MODEL_PATH = "./models/layoutlmv3_model"
# WEIGHTS_PATH = "./weights/yolo_weights.pt"
# def process_pdf(pdf_file, layoutlmv3_model_path=None):
# """
# Wrapper function for Gradio interface.
# Args:
# pdf_file: Gradio UploadButton file object
# layoutlmv3_model_path: Optional custom model path
# Returns:
# Tuple of (JSON string, download file path)
# """
# if pdf_file is None:
# return "❌ Error: No PDF file uploaded.", None
# # Use default model path if not provided
# if not layoutlmv3_model_path:
# layoutlmv3_model_path = DEFAULT_LAYOUTLMV3_MODEL_PATH
# # Verify model and weights exist
# if not os.path.exists(layoutlmv3_model_path):
# return f"❌ Error: LayoutLMv3 model not found at {layoutlmv3_model_path}", None
# if not os.path.exists(WEIGHTS_PATH):
# return f"❌ Error: YOLO weights not found at {WEIGHTS_PATH}", None
# try:
# # Get the uploaded PDF path
# pdf_path = pdf_file.name
# # Run the pipeline
# result = run_document_pipeline(pdf_path, layoutlmv3_model_path, 'label_studio_import.json')
# if result is None:
# return "❌ Error: Pipeline failed to process the PDF. Check console for details.", None
# # Create a temporary file for download
# output_filename = f"{Path(pdf_path).stem}_analysis.json"
# temp_output = tempfile.NamedTemporaryFile(mode='w', delete=False, suffix='.json', prefix='analysis_')
# # Dump results to the temporary file
# with open(temp_output.name, 'w', encoding='utf-8') as f:
# json.dump(result, f, indent=2, ensure_ascii=False)
# # Format JSON for display
# json_display = json.dumps(result, indent=2, ensure_ascii=False)
# return json_display, temp_output.name
# except Exception as e:
# return f"❌ Error during processing: {str(e)}", None
# # Create Gradio interface
# # FIX APPLIED: Removed 'theme=gr.themes.Soft()' which caused the TypeError
# with gr.Blocks(title="Document Analysis Pipeline") as demo:
# gr.Markdown("""
# # πŸ“„ Document Analysis Pipeline
# Upload a PDF document to extract structured data including questions, options, answers, passages, and embedded images.
# **Pipeline Steps:**
# 1. πŸ” YOLO/OCR Preprocessing (word extraction + figure/equation detection)
# 2. πŸ€– LayoutLMv3 Inference (BIO tagging)
# 3. πŸ“Š Structured JSON Decoding
# 4. πŸ–ΌοΈ Base64 Image Embedding
# """)
# with gr.Row():
# with gr.Column(scale=1):
# pdf_input = gr.File(
# label="Upload PDF Document",
# file_types=[".pdf"],
# type="filepath"
# )
# model_path_input = gr.Textbox(
# label="LayoutLMv3 Model Path (optional)",
# placeholder=DEFAULT_LAYOUTLMV3_MODEL_PATH,
# value=DEFAULT_LAYOUTLMV3_MODEL_PATH,
# interactive=True
# )
# process_btn = gr.Button("πŸš€ Process Document", variant="primary", size="lg")
# gr.Markdown("""
# ### ℹ️ Notes:
# - Processing may take several minutes depending on PDF size
# - Figures and equations will be extracted and embedded as Base64
# - The output JSON includes structured questions, options, and answers
# """)
# with gr.Column(scale=2):
# json_output = gr.Code(
# label="Structured JSON Output",
# language="json",
# lines=25
# )
# download_output = gr.File(
# label="Download Full JSON",
# interactive=False
# )
# # Status/Examples section
# with gr.Row():
# gr.Markdown("""
# ### πŸ“‹ Output Format
# The pipeline generates JSON with the following structure:
# - **Questions**: Extracted question text
# - **Options**: Multiple choice options (A, B, C, D, etc.)
# - **Answers**: Correct answer(s)
# - **Passages**: Associated reading passages
# - **Images**: Base64-encoded figures and equations (embedded with keys like `figure1`, `equation2`)
# """)
# # Connect the button to the processing function
# process_btn.click(
# fn=process_pdf,
# inputs=[pdf_input, model_path_input],
# outputs=[json_output, download_output],
# api_name="process_document"
# )
# # Example section (optional - add example PDFs if available)
# # gr.Examples(
# # examples=[
# # ["examples/sample1.pdf"],
# # ["examples/sample2.pdf"],
# # ],
# # inputs=pdf_input,
# # )
# # Launch the app
# if __name__ == "__main__":
# demo.launch(
# server_name="0.0.0.0",
# server_port=7860,
# share=False,
# show_error=True
# )
import gradio as gr
print("GRADIO VERSION:", gr.__version__)
import json
import os
import tempfile
from pathlib import Path
# ==============================
# WRITE CUSTOM CSS FOR FONTS
# ==============================
# CUSTOM_CSS = """
# @font-face {
# font-family: 'NotoSansMath';
# src: url('./NotoSansMath-Regular.ttf') format('truetype');
# font-weight: normal;
# font-style: normal;
# }
# html, body, * {
# font-family: 'NotoSansMath', sans-serif !important;
# }
# """
# # Optionally write the CSS file if needed (not required for inline css)
# if not os.path.exists("custom.css"):
# with open("custom.css", "w") as f:
# f.write(CUSTOM_CSS)
# ==============================
try:
from working_yolo_pipeline import run_document_pipeline, DEFAULT_LAYOUTLMV3_MODEL_PATH, WEIGHTS_PATH
except ImportError:
print("Warning: 'working_yolo_pipeline.py' not found. Using dummy paths.")
def run_document_pipeline(*args):
return {"error": "Placeholder pipeline function called."}
DEFAULT_LAYOUTLMV3_MODEL_PATH = "./models/layoutlmv3_model"
WEIGHTS_PATH = "./weights/yolo_weights.pt"
def process_pdf(pdf_file, layoutlmv3_model_path=None):
if pdf_file is None:
return "❌ Error: No PDF file uploaded.", None
if not layoutlmv3_model_path:
layoutlmv3_model_path = DEFAULT_LAYOUTLMV3_MODEL_PATH
if not os.path.exists(layoutlmv3_model_path):
return f"❌ Error: LayoutLMv3 model not found at {layoutlmv3_model_path}", None
if not os.path.exists(WEIGHTS_PATH):
return f"❌ Error: YOLO weights not found at {WEIGHTS_PATH}", None
try:
pdf_path = pdf_file.name
result = run_document_pipeline(pdf_path, layoutlmv3_model_path, 'label_studio_import.json')
if result is None:
return "❌ Error: Pipeline failed to process the PDF. Check console for details.", None
output_filename = f"{Path(pdf_path).stem}_analysis.json"
temp_output = tempfile.NamedTemporaryFile(mode='w', delete=False, suffix='.json', prefix='analysis_')
with open(temp_output.name, 'w', encoding='utf-8') as f:
json.dump(result, f, indent=2, ensure_ascii=False)
json_display = json.dumps(result, indent=2, ensure_ascii=False)
return json_display, temp_output.name
except Exception as e:
return f"❌ Error during processing: {str(e)}", None
with gr.Blocks(
title="Document Analysis Pipeline"
) as demo:
gr.HTML()
gr.Markdown("""
# πŸ“„ Document Analysis Pipeline
Upload a PDF document to extract structured data including questions, options, answers, passages, and embedded images.
**Pipeline Steps:**
1. πŸ” YOLO/OCR Preprocessing (word extraction + figure/equation detection)
2. πŸ€– LayoutLMv3 Inference (BIO tagging)
3. πŸ“Š Structured JSON Decoding
4. πŸ–ΌοΈ Base64 Image Embedding
""")
with gr.Row():
with gr.Column(scale=1):
pdf_input = gr.File(
label="Upload PDF Document",
file_types=[".pdf"],
type="filepath"
)
model_path_input = gr.Textbox(
label="LayoutLMv3 Model Path (optional)",
placeholder=DEFAULT_LAYOUTLMV3_MODEL_PATH,
value=DEFAULT_LAYOUTLMV3_MODEL_PATH,
interactive=True
)
process_btn = gr.Button("πŸš€ Process Document", variant="primary", size="lg")
gr.Markdown("""
### ℹ️ Notes:
- Processing may take several minutes depending on PDF size
- Figures and equations will be extracted and embedded as Base64
- The output JSON includes structured questions, options, and answers
""")
with gr.Column(scale=2):
json_output = gr.Code(
label="Structured JSON Output",
language="json",
lines=25
)
download_output = gr.File(
label="Download Full JSON",
interactive=False
)
with gr.Row():
gr.Markdown("""
### πŸ“‹ Output Format
The pipeline generates JSON with the following structure:
- **Questions**: Extracted question text
- **Options**: Multiple choice options
- **Answers**: Correct answer(s)
- **Passages**: Associated reading passages
- **Images**: Base64-encoded figures and equations
""")
process_btn.click(
fn=process_pdf,
inputs=[pdf_input, model_path_input],
outputs=[json_output, download_output],
api_name="process_document"
)
if __name__ == "__main__":
demo.launch(
server_name="0.0.0.0",
server_port=7860,
ssr_mode=False, # πŸ”₯ FIXES YOUR ERROR
show_error=True,
# These two prevent asyncio cleanup issues
enable_queue=True,
max_threads=1,
)