spagestic commited on
Commit
19033cb
Β·
1 Parent(s): 7f023d8

feat: Enhance PDF extraction interface with improved layout and error handling

Browse files
Files changed (3) hide show
  1. _app.py +64 -5
  2. requirements.txt +2 -2
  3. ui/interface.py +83 -69
_app.py CHANGED
@@ -1,9 +1,68 @@
1
  import gradio as gr
2
  from gradio_pdf import PDF
 
3
 
4
- with gr.Blocks() as demo:
5
- pdf = PDF(label="Upload a PDF", interactive=True)
6
- name = gr.Textbox()
7
- pdf.upload(lambda f: f, pdf, name)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
 
9
- demo.launch()
 
 
 
1
  import gradio as gr
2
  from gradio_pdf import PDF
3
+ from pdf_text_extractor import PDFTextExtractor
4
 
5
+ def main():
6
+ """Main function to create and launch the interface."""
7
+ def process_pdf(pdf_file):
8
+ """Process PDF and extract text automatically"""
9
+ if pdf_file is None:
10
+ return "", "No PDF uploaded"
11
+
12
+ try:
13
+ # Initialize extractor
14
+ extractor = PDFTextExtractor()
15
+
16
+ # Extract text from PDF
17
+ extracted_text, status, images_data = extractor.extract_text_from_pdf(pdf_file)
18
+
19
+ return extracted_text, status
20
+
21
+ except Exception as e:
22
+ return "", f"Error processing PDF: {str(e)}"
23
+
24
+ # Create the interface with side-by-side layout
25
+ with gr.Blocks(title="πŸ” PDF Text Extractor", theme=gr.themes.Soft()) as demo:
26
+ gr.Markdown("# πŸ” PDF Text Extractor")
27
+ gr.Markdown("Upload a PDF on the left to automatically extract and view text on the right.")
28
+
29
+ with gr.Row(equal_height=True):
30
+ # Left column - PDF Display
31
+ with gr.Column(scale=1):
32
+ gr.Markdown("### πŸ“„ PDF Document")
33
+ pdf_input = PDF(
34
+ label="Upload and View PDF",
35
+ height=600,
36
+ interactive=True
37
+ )
38
+
39
+ status_output = gr.Textbox(
40
+ label="Status",
41
+ lines=2,
42
+ placeholder="Upload a PDF to see status...",
43
+ interactive=False
44
+ )
45
+
46
+ # Right column - Extracted Text
47
+ with gr.Column(scale=1):
48
+ gr.Markdown("### πŸ“ Extracted Text")
49
+ text_output = gr.Textbox(
50
+ label="Extracted Text",
51
+ lines=25,
52
+ placeholder="Upload a PDF to automatically extract text...",
53
+ show_copy_button=True,
54
+ interactive=False
55
+ )
56
+
57
+ # Set up automatic processing on PDF upload
58
+ pdf_input.upload(
59
+ fn=process_pdf,
60
+ inputs=[pdf_input],
61
+ outputs=[text_output, status_output]
62
+ )
63
+
64
+ return demo
65
 
66
+ if __name__ == "__main__":
67
+ demo = main()
68
+ demo.launch()
requirements.txt CHANGED
@@ -14,6 +14,7 @@ filelock==3.18.0
14
  fsspec==2025.5.1
15
  gradio==5.33.0
16
  gradio_client==1.10.2
 
17
  groovy==0.1.2
18
  h11==0.16.0
19
  httpcore==1.0.9
@@ -57,5 +58,4 @@ typing_extensions==4.14.0
57
  tzdata==2025.2
58
  urllib3==2.4.0
59
  uvicorn==0.34.3
60
- websockets==15.0.1
61
- gradio_pdf
 
14
  fsspec==2025.5.1
15
  gradio==5.33.0
16
  gradio_client==1.10.2
17
+ gradio-pdf==0.0.15
18
  groovy==0.1.2
19
  h11==0.16.0
20
  httpcore==1.0.9
 
58
  tzdata==2025.2
59
  urllib3==2.4.0
60
  uvicorn==0.34.3
61
+ websockets==15.0.1
 
ui/interface.py CHANGED
@@ -4,6 +4,7 @@ Defines the Gradio interface components and layout.
4
  """
5
 
6
  import gradio as gr
 
7
  from pdf_text_extractor import PDFTextExtractor
8
  from ui.handlers import process_images_for_display
9
  from .components.create_header import create_header
@@ -27,26 +28,34 @@ def create_dummy_interface() -> gr.Blocks:
27
  ⚠️ **API key not configured.** Please set MISTRAL_API_KEY environment variable and restart the application.
28
  """)
29
 
30
- with gr.Row():
31
- gr.File(label="Upload PDF", file_types=[".pdf"])
32
-
33
- with gr.Row():
34
- gr.Button("Extract Text", variant="primary", interactive=False)
35
-
36
- with gr.Row():
37
- gr.Textbox(
38
- label="Extracted Text",
39
- lines=10,
40
- value="API key not configured. Text extraction is unavailable.",
41
- interactive=False
42
- )
43
-
44
- with gr.Row():
45
- gr.Textbox(
46
- label="Status",
47
- lines=2,
48
- value="❌ MISTRAL_API_KEY environment variable is not set. Please set it and restart the application."
49
- )
 
 
 
 
 
 
 
 
50
 
51
  return interface
52
 
@@ -98,7 +107,6 @@ def create_main_interface(extractor: PDFTextExtractor) -> gr.Blocks:
98
 
99
  # Call the TTS function directly - it already handles gr.Error exceptions properly
100
  return generate_tts_audio(clean_text, None)
101
-
102
  def tts_click_handler(explanations_text):
103
  """Handle TTS button click with proper output handling"""
104
  try:
@@ -115,59 +123,65 @@ def create_main_interface(extractor: PDFTextExtractor) -> gr.Blocks:
115
  # Add the header
116
  create_header()
117
 
118
- # Add file upload section
119
- with gr.Row():
120
- pdf_input = create_upload_section()
121
-
122
- # Add extract button
123
- with gr.Row():
124
- submit_btn = create_action_button()
125
-
126
- # Add status display
127
- with gr.Row():
128
- status_output = gr.Textbox(
129
- label="Status",
130
- lines=2,
131
- placeholder="Upload a PDF to see status..."
132
- )
133
-
134
- # Create tabs for text, explanations, and images
135
- with gr.Tabs():
136
- with gr.TabItem("Extracted Text"):
137
- text_output = gr.Textbox(
138
- label="Extracted Text",
139
- lines=15,
140
- max_lines=30,
141
- placeholder="Extracted text will appear here...",
142
- show_copy_button=True
143
  )
144
-
145
- with gr.TabItem("πŸ“š Explanations"):
146
- with gr.Row():
147
- explain_btn = gr.Button("πŸ€– Generate Explanations", variant="secondary", size="lg")
148
- tts_btn = gr.Button("πŸ”Š Generate Audio", variant="secondary", size="lg")
149
 
150
- explanations_output = gr.Textbox(
151
- label="Text Explanations",
152
- lines=20,
153
- max_lines=40,
154
- placeholder="Click 'Generate Explanations' after extracting text to get simple explanations of each section...",
155
- show_copy_button=True
156
  )
 
 
 
 
157
 
158
- # Add audio output for explanations
159
- explanation_audio_output = gr.Audio(
160
- label="Explanation Audio",
161
- interactive=False,
162
- visible=False
163
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
164
 
165
- with gr.TabItem("Extracted Images"):
166
- image_gallery = create_image_gallery()
167
- image_info = gr.Markdown("Images extracted from the PDF will appear here.")
168
-
169
- # Set up function calls
170
- submit_btn.click(
171
  fn=process_pdf_wrapper,
172
  inputs=[pdf_input],
173
  outputs=[text_output, status_output, image_gallery]
 
4
  """
5
 
6
  import gradio as gr
7
+ from gradio_pdf import PDF
8
  from pdf_text_extractor import PDFTextExtractor
9
  from ui.handlers import process_images_for_display
10
  from .components.create_header import create_header
 
28
  ⚠️ **API key not configured.** Please set MISTRAL_API_KEY environment variable and restart the application.
29
  """)
30
 
31
+ # Create layout similar to main interface but disabled
32
+ with gr.Row(equal_height=True):
33
+ # Left column - PDF Display
34
+ with gr.Column(scale=1):
35
+ gr.Markdown("### πŸ“„ PDF Document")
36
+ PDF(
37
+ label="Upload and View PDF (Disabled)",
38
+ height=700,
39
+ interactive=False
40
+ )
41
+
42
+ gr.Textbox(
43
+ label="Status",
44
+ lines=2,
45
+ value="❌ MISTRAL_API_KEY environment variable is not set. Please set it and restart the application.",
46
+ interactive=False
47
+ )
48
+
49
+ # Right column - Extracted Content
50
+ with gr.Column(scale=1):
51
+ gr.Markdown("### πŸ“ Extracted Content")
52
+
53
+ gr.Textbox(
54
+ label="Extracted Text",
55
+ lines=25,
56
+ value="API key not configured. Text extraction is unavailable.",
57
+ interactive=False
58
+ )
59
 
60
  return interface
61
 
 
107
 
108
  # Call the TTS function directly - it already handles gr.Error exceptions properly
109
  return generate_tts_audio(clean_text, None)
 
110
  def tts_click_handler(explanations_text):
111
  """Handle TTS button click with proper output handling"""
112
  try:
 
123
  # Add the header
124
  create_header()
125
 
126
+ # Create main layout with PDF on left and content on right
127
+ with gr.Row(equal_height=True):
128
+ # Left column - PDF Display
129
+ with gr.Column(scale=1):
130
+ gr.Markdown("### πŸ“„ PDF Document")
131
+ pdf_input = PDF(
132
+ label="Upload and View PDF",
133
+ height=700,
134
+ interactive=True
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
135
  )
 
 
 
 
 
136
 
137
+ # Status display below PDF
138
+ status_output = gr.Textbox(
139
+ label="Status",
140
+ lines=2,
141
+ placeholder="Upload a PDF to see status...",
142
+ interactive=False
143
  )
144
+
145
+ # Right column - Extracted Content
146
+ with gr.Column(scale=1):
147
+ gr.Markdown("### πŸ“ Extracted Content")
148
 
149
+ # Create tabs for text, explanations, and images
150
+ with gr.Tabs():
151
+ with gr.TabItem("Extracted Text"):
152
+ text_output = gr.Textbox(
153
+ label="Extracted Text",
154
+ lines=25,
155
+ max_lines=30,
156
+ placeholder="Upload a PDF to automatically extract text...",
157
+ show_copy_button=True
158
+ )
159
+
160
+ with gr.TabItem("πŸ“š Explanations"):
161
+ with gr.Row():
162
+ explain_btn = gr.Button("πŸ€– Generate Explanations", variant="secondary", size="lg")
163
+ tts_btn = gr.Button("πŸ”Š Generate Audio", variant="secondary", size="lg")
164
+
165
+ explanations_output = gr.Textbox(
166
+ label="Text Explanations",
167
+ lines=20,
168
+ max_lines=25,
169
+ placeholder="Click 'Generate Explanations' after extracting text to get simple explanations of each section...",
170
+ show_copy_button=True
171
+ )
172
+
173
+ # Add audio output for explanations
174
+ explanation_audio_output = gr.Audio(
175
+ label="Explanation Audio",
176
+ interactive=False,
177
+ visible=False
178
+ )
179
 
180
+ with gr.TabItem("Extracted Images"):
181
+ image_gallery = create_image_gallery()
182
+ image_info = gr.Markdown("Images extracted from the PDF will appear here.")
183
+ # Set up automatic PDF processing on upload
184
+ pdf_input.upload(
 
185
  fn=process_pdf_wrapper,
186
  inputs=[pdf_input],
187
  outputs=[text_output, status_output, image_gallery]