datasaur-dev commited on
Commit
f97ef15
·
verified ·
1 Parent(s): 1bb5b82

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +54 -165
app.py CHANGED
@@ -3,14 +3,10 @@ import json
3
  import gradio as gr
4
  import pandas as pd
5
  from python_request import process_wod_document
 
6
  import time
7
  from dummy import output_test
8
 
9
- # --- Global Variables for Timer ---
10
- processing_start_time = None
11
- is_processing = False
12
- analysis_completed = False
13
-
14
  # --- Authentication Function ---
15
  def authenticate_user(username, password):
16
  """
@@ -19,20 +15,6 @@ def authenticate_user(username, password):
19
  """
20
  return username == "demo" and password == os.environ["PASSWORD"]
21
 
22
- def update_processing_timer():
23
- """
24
- Update the processing button with elapsed time ONLY during active processing
25
- """
26
- global processing_start_time, is_processing, analysis_completed
27
-
28
- # Only update button during active processing
29
- if is_processing and processing_start_time is not None:
30
- elapsed = int(time.time() - processing_start_time)
31
- return gr.Button(f"Processing... ({elapsed}s)", variant="primary", interactive=False)
32
-
33
- # Don't interfere with button state when not processing
34
- return gr.update()
35
-
36
  # --- Core Application Logic ---
37
  def analyze_wod(file_obj, wod_type):
38
  """
@@ -43,17 +25,18 @@ def analyze_wod(file_obj, wod_type):
43
  wod_type: The selected type of Work Order Document.
44
 
45
  Returns:
46
- A tuple containing: prediction_display, DataFrame, updated button, file_input, type_input
47
  """
48
- global is_processing, analysis_completed
49
- # These checks are now done earlier, but keeping as safety net
50
  if wod_type == "-- WOD type --" or wod_type is None:
 
51
  gr.Warning("Please select a WOD type first!")
52
- return "", pd.DataFrame(), gr.Button("Analyze Document", variant="primary", interactive=True), file_obj, wod_type
53
 
 
54
  if file_obj is None:
55
  gr.Warning("Please upload a PDF file first!")
56
- return "", pd.DataFrame(), gr.Button("Analyze Document", variant="primary", interactive=True), file_obj, wod_type
57
 
58
  print(f"Analyzing '{file_obj.name}' (Type: {wod_type})...")
59
 
@@ -71,7 +54,7 @@ def analyze_wod(file_obj, wod_type):
71
 
72
  # Process the document using the API
73
  api_response = process_wod_document(temp_file_path, wod_type)
74
- # time.sleep(3)
75
  # api_response = json.loads(output_test)
76
 
77
  # Clean up temporary file if we created one
@@ -80,13 +63,9 @@ def analyze_wod(file_obj, wod_type):
80
 
81
  # Check if API call was successful
82
  if api_response.get("status") != "success":
83
- # Stop processing timer on API error
84
- is_processing = False
85
- analysis_completed = False
86
-
87
  error_msg = api_response.get("message", "Unknown error occurred")
88
  gr.Error(f"API Error: {error_msg}")
89
- return "", pd.DataFrame(), gr.Button("Analyze Document", variant="primary", interactive=True), file_obj, wod_type
90
 
91
  # Parse the API response
92
  results = api_response.get("results", {})
@@ -117,118 +96,25 @@ def analyze_wod(file_obj, wod_type):
117
 
118
  # Get prediction for display
119
  prediction = results.get("prediction", "Unknown")
120
- # gr.Info(f"Analysis completed! Overall prediction: {prediction}")
121
 
122
  # Format prediction as centered H1 for display
123
  prediction_display = f"<h1 style='text-align: center; color: #1f77b4;'>{prediction}</h1>" if prediction != "Unknown" else ""
124
 
125
- # Stop processing timer and mark analysis as completed
126
- is_processing = False
127
- analysis_completed = True
128
-
129
- # Return results with reset button, keeping current inputs
130
- return prediction_display, df, gr.Button("Reset", variant="secondary", interactive=True), file_obj, wod_type
131
 
132
  except Exception as e:
133
- # Stop processing timer on error
134
- is_processing = False
135
- analysis_completed = False
136
-
137
  error_msg = f"Error processing document: {str(e)}"
138
  print(error_msg)
139
  gr.Error(error_msg)
140
- return "", pd.DataFrame(), gr.Button("Analyze Document", variant="primary", interactive=True), file_obj, wod_type
141
-
142
- def reset_interface():
143
- """
144
- Reset the interface to initial state
145
- """
146
- global analysis_completed, is_processing
147
-
148
- # Reset global state
149
- analysis_completed = False
150
- is_processing = False
151
-
152
- # Create completely clean DataFrame to avoid any pandas confusion
153
- clean_df = pd.DataFrame(columns=["Requirement", "Reason", "Status"])
154
-
155
- return (
156
- None, # Clear file input
157
- "-- WOD type --", # Reset dropdown
158
- "", # Clear prediction output
159
- clean_df, # Clear results with proper columns
160
- gr.Button("Analyze Document", variant="primary", interactive=True) # Reset button
161
- )
162
-
163
- def check_button_state_and_act(file_obj, wod_type, button_state):
164
- """
165
- Check button state and decide what to do
166
- """
167
- # Get button text safely
168
- try:
169
- button_text = button_state.value if hasattr(button_state, 'value') else str(button_state)
170
- except:
171
- button_text = "Analyze Document" # Default fallback
172
-
173
- # If button shows "Reset", we'll let JavaScript handle the page refresh
174
- if "Reset" in button_text:
175
- # Return current state - JavaScript will refresh the page
176
- clean_df = pd.DataFrame(columns=["Requirement", "Reason", "Status"])
177
- return "", clean_df, button_state, file_obj, wod_type
178
-
179
- # If button shows "Analyze Document", check requirements first
180
- elif "Analyze Document" in button_text:
181
- # Check if WOD type is selected
182
- if wod_type == "-- WOD type --" or wod_type is None:
183
- gr.Warning("Please select a WOD type first!")
184
- clean_df = pd.DataFrame(columns=["Requirement", "Reason", "Status"])
185
- return "", clean_df, gr.Button("Analyze Document", variant="primary", interactive=True), file_obj, wod_type
186
-
187
- # Check if file is uploaded
188
- if file_obj is None:
189
- gr.Warning("Please upload a PDF file first!")
190
- clean_df = pd.DataFrame(columns=["Requirement", "Reason", "Status"])
191
- return "", clean_df, gr.Button("Analyze Document", variant="primary", interactive=True), file_obj, wod_type
192
-
193
- # All requirements met, start processing timer
194
- global processing_start_time, is_processing, analysis_completed
195
- processing_start_time = time.time()
196
- is_processing = True
197
- analysis_completed = False
198
-
199
- clean_df = pd.DataFrame(columns=["Requirement", "Reason", "Status"])
200
- # Return loading state and flag for next step
201
- return "", clean_df, gr.Button("Processing... (0s)", variant="primary", interactive=False), file_obj, wod_type
202
-
203
- # Fallback case
204
- return "", pd.DataFrame(columns=["Requirement", "Reason", "Status"]), gr.Button("Analyze Document", variant="primary", interactive=True), file_obj, wod_type
205
 
206
- def perform_analysis_if_needed(pred, df, button_state, file_obj, wod_type):
207
  """
208
- Perform analysis if button was in processing state
209
  """
210
- # Get button text safely
211
- try:
212
- button_text = button_state.value if hasattr(button_state, 'value') else str(button_state)
213
- except:
214
- button_text = "Analyze Document" # Default fallback
215
-
216
- # If button shows "Processing...", perform analysis
217
- if "Processing" in button_text:
218
- # Inputs are already validated, proceed with analysis
219
- return analyze_wod(file_obj, wod_type)
220
-
221
- # If button shows "Analyze Document" (after reset or clean state), ensure clean state
222
- elif "Analyze Document" in button_text:
223
- # Ensure we have clean DataFrame with proper columns
224
- if df.empty or len(df.columns) == 0:
225
- clean_df = pd.DataFrame(columns=["Requirement", "Reason", "Status"])
226
- else:
227
- clean_df = df
228
- return pred, clean_df, button_state, file_obj, wod_type
229
-
230
- # Otherwise, keep current state
231
- return pred, df, button_state, file_obj, wod_type
232
 
233
  js_func = """
234
  function refresh() {
@@ -241,13 +127,24 @@ function refresh() {
241
  }
242
  """
243
 
 
 
 
 
 
 
 
 
 
 
 
244
  # --- Gradio User Interface Definition ---
245
  # Using gr.Blocks() for a custom layout that matches the elegant design.
246
  with gr.Blocks(
247
  #theme=gr.themes.Soft(primary_hue="blue", secondary_hue="sky"),
248
- js=js_func,
249
  theme=gr.themes.Default(primary_hue="blue", secondary_hue="sky"),
250
- css=".gradio-container {max-width: 960px !important; margin: auto !important;}"
 
251
  ) as demo:
252
 
253
  # Main Title and Description
@@ -291,43 +188,35 @@ with gr.Blocks(
291
  wrap=True
292
  )
293
 
294
- # JavaScript to handle reset button
295
- reset_js = """
296
- function(file_obj, wod_type, button_state) {
297
- // Get button text
298
- let button_text = typeof button_state === 'object' && button_state.value ? button_state.value : button_state.toString();
299
-
300
- // If it's reset button, refresh the page
301
- if (button_text.includes('Reset')) {
302
- setTimeout(() => {
303
- window.location.reload();
304
- }, 100);
305
- }
306
-
307
- // Return the inputs as-is for the Python function
308
- return [file_obj, wod_type, button_state];
309
- }
310
- """
311
-
312
  # Define the interaction: clicking the button calls the function
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
313
  analyze_btn.click(
314
- fn=check_button_state_and_act,
315
- inputs=[file_input, type_input, analyze_btn],
316
- outputs=[prediction_output, results_output, analyze_btn, file_input, type_input],
317
  show_progress=False,
318
- js=reset_js
319
  ).then(
320
- fn=perform_analysis_if_needed,
321
- inputs=[prediction_output, results_output, analyze_btn, file_input, type_input],
322
- outputs=[prediction_output, results_output, analyze_btn, file_input, type_input],
323
- show_progress=False
324
- )
325
-
326
- # Add timer to update processing button every second
327
- timer = gr.Timer(1.0) # Update every 1 second
328
- timer.tick(
329
- fn=update_processing_timer,
330
- outputs=[analyze_btn]
331
  )
332
 
333
  # --- Launch the Application with Authentication ---
 
3
  import gradio as gr
4
  import pandas as pd
5
  from python_request import process_wod_document
6
+
7
  import time
8
  from dummy import output_test
9
 
 
 
 
 
 
10
  # --- Authentication Function ---
11
  def authenticate_user(username, password):
12
  """
 
15
  """
16
  return username == "demo" and password == os.environ["PASSWORD"]
17
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
  # --- Core Application Logic ---
19
  def analyze_wod(file_obj, wod_type):
20
  """
 
25
  wod_type: The selected type of Work Order Document.
26
 
27
  Returns:
28
+ A tuple containing: prediction_display, dataframe, and button_update
29
  """
30
+ # Check if user has selected a valid WOD type
 
31
  if wod_type == "-- WOD type --" or wod_type is None:
32
+ # Show warning dialog and return empty DataFrame
33
  gr.Warning("Please select a WOD type first!")
34
+ return "", pd.DataFrame(), gr.update(value="Analyze Document", interactive=True)
35
 
36
+ # Check if file is uploaded
37
  if file_obj is None:
38
  gr.Warning("Please upload a PDF file first!")
39
+ return "", pd.DataFrame(), gr.update(value="Analyze Document", interactive=True)
40
 
41
  print(f"Analyzing '{file_obj.name}' (Type: {wod_type})...")
42
 
 
54
 
55
  # Process the document using the API
56
  api_response = process_wod_document(temp_file_path, wod_type)
57
+ # time.sleep(5)
58
  # api_response = json.loads(output_test)
59
 
60
  # Clean up temporary file if we created one
 
63
 
64
  # Check if API call was successful
65
  if api_response.get("status") != "success":
 
 
 
 
66
  error_msg = api_response.get("message", "Unknown error occurred")
67
  gr.Error(f"API Error: {error_msg}")
68
+ return "", pd.DataFrame(), gr.update(value="Analyze Document", interactive=True)
69
 
70
  # Parse the API response
71
  results = api_response.get("results", {})
 
96
 
97
  # Get prediction for display
98
  prediction = results.get("prediction", "Unknown")
99
+ gr.Info(f"Analysis completed! Overall prediction: {prediction}")
100
 
101
  # Format prediction as centered H1 for display
102
  prediction_display = f"<h1 style='text-align: center; color: #1f77b4;'>{prediction}</h1>" if prediction != "Unknown" else ""
103
 
104
+ # Return with Reset button
105
+ return prediction_display, df, gr.update(value="Reset", interactive=True)
 
 
 
 
106
 
107
  except Exception as e:
 
 
 
 
108
  error_msg = f"Error processing document: {str(e)}"
109
  print(error_msg)
110
  gr.Error(error_msg)
111
+ return "", pd.DataFrame(), gr.update(value="Analyze Document", interactive=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
112
 
113
+ def reset_app():
114
  """
115
+ Reset function that refreshes the page using JavaScript
116
  """
117
+ return gr.update(value="Analyze Document", interactive=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
118
 
119
  js_func = """
120
  function refresh() {
 
127
  }
128
  """
129
 
130
+ # JavaScript function to refresh the page when Reset is clicked
131
+ refresh_js = """
132
+ function(button_value) {
133
+ if (button_value === "Reset") {
134
+ window.location.reload();
135
+ return false; // Prevent default action
136
+ }
137
+ return true;
138
+ }
139
+ """
140
+
141
  # --- Gradio User Interface Definition ---
142
  # Using gr.Blocks() for a custom layout that matches the elegant design.
143
  with gr.Blocks(
144
  #theme=gr.themes.Soft(primary_hue="blue", secondary_hue="sky"),
 
145
  theme=gr.themes.Default(primary_hue="blue", secondary_hue="sky"),
146
+ js=js_func,
147
+ css=".gradio-container {max-width: 960px !important; margin: auto !important;} .progress-text { display: none !important; }"
148
  ) as demo:
149
 
150
  # Main Title and Description
 
188
  wrap=True
189
  )
190
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
191
  # Define the interaction: clicking the button calls the function
192
+ def handle_button_click(file_obj, wod_type, current_button_value):
193
+ """Handle button click with state management"""
194
+ # Check if this is a reset action (this shouldn't be reached due to JS)
195
+ if current_button_value == "Reset":
196
+ return "", pd.DataFrame(), gr.update(value="Analyze Document", interactive=True)
197
+
198
+ # Otherwise, this is an analyze action
199
+ prediction_display, df, button_update = analyze_wod(file_obj, wod_type)
200
+ return prediction_display, df, button_update
201
+
202
+ # Set button to Processing state when clicked (only if not Reset)
203
+ def set_processing_state(current_button_value):
204
+ if current_button_value == "Reset":
205
+ return gr.update() # Don't change if it's reset
206
+ return gr.update(value="Processing...", interactive=False)
207
+
208
+ # Chain the events: first set processing state, then analyze
209
  analyze_btn.click(
210
+ fn=set_processing_state,
211
+ inputs=[analyze_btn],
212
+ outputs=[analyze_btn],
213
  show_progress=False,
214
+ js=refresh_js # Add JavaScript to handle reset
215
  ).then(
216
+ fn=handle_button_click,
217
+ inputs=[file_input, type_input, analyze_btn],
218
+ outputs=[prediction_output, results_output, analyze_btn],
219
+ show_progress=True
 
 
 
 
 
 
 
220
  )
221
 
222
  # --- Launch the Application with Authentication ---