geekgirl3 commited on
Commit
fd45c09
·
verified ·
1 Parent(s): 9eaf386

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +98 -9
app.py CHANGED
@@ -7,6 +7,7 @@ from typing import Tuple, Dict, Any, Optional
7
  import tempfile
8
  import io
9
  import datetime
 
10
 
11
  class FeedbackTransformer:
12
  """
@@ -258,6 +259,31 @@ class FeedbackTransformer:
258
 
259
  return analysis_text
260
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
261
  def save_transformed_data(self, output_format='xlsx'):
262
  """
263
  Save the transformed data and return the file path.
@@ -379,6 +405,7 @@ def process_file(file_obj, topic_prefix, sentiment_prefix, category_prefix,
379
  text_column, recommendation_column, output_format, analyze_data, selected_columns):
380
  """
381
  Main processing function for Gradio interface.
 
382
  """
383
  try:
384
  # Extract actual column names from display format
@@ -423,15 +450,58 @@ def process_file(file_obj, topic_prefix, sentiment_prefix, category_prefix,
423
  if analyze_data:
424
  analysis_result = transformer.analyze_data()
425
 
426
- # Save transformed data
427
  output_file = transformer.save_transformed_data(output_format)
428
- status_msg += f"\n💾 File saved successfully: {os.path.basename(output_file)}\n"
 
 
 
 
429
 
430
- return status_msg, analysis_result, output_file
431
 
432
  except Exception as e:
433
  error_msg = f"❌ Error: {str(e)}\n\n{traceback.format_exc()}"
434
- return error_msg, "", None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
435
 
436
 
437
  # Create Gradio interface
@@ -453,7 +523,7 @@ with gr.Blocks(title="Feedback Topic & Sentiment Transformer", css="""
453
  2. Select which original columns to include in the output
454
  3. Configure column prefixes (or use defaults)
455
  4. Click "Transform Data" to process
456
- 5. Download the transformed file
457
  """)
458
 
459
  with gr.Row():
@@ -537,16 +607,30 @@ with gr.Blocks(title="Feedback Topic & Sentiment Transformer", css="""
537
  label="Data Analysis"
538
  )
539
 
540
- # Download section - Modified for better download functionality
541
  with gr.Row():
542
  with gr.Column():
543
  gr.Markdown("### �� 5. Download Transformed File")
 
 
 
 
 
 
 
 
 
 
 
544
  output_file = gr.File(
545
- label="Transformed File",
546
  interactive=False,
547
  visible=True
548
  )
549
 
 
 
 
550
  # Event handlers
551
  input_file.change(
552
  fn=get_column_selector,
@@ -567,7 +651,11 @@ with gr.Blocks(title="Feedback Topic & Sentiment Transformer", css="""
567
  analyze_checkbox,
568
  column_selector
569
  ],
570
- outputs=[status_output, analysis_output, output_file]
 
 
 
 
571
  )
572
 
573
  # Examples section
@@ -589,7 +677,8 @@ with gr.Blocks(title="Feedback Topic & Sentiment Transformer", css="""
589
  - Use the numbered column list to easily identify and select columns
590
  - The text and recommendation column names in configuration are now for reference only
591
  - To include them in output, select them using the column checkboxes
592
- - Click on the download button that appears after processing to download the file
 
593
  """)
594
 
595
  # Launch the app
 
7
  import tempfile
8
  import io
9
  import datetime
10
+ import base64
11
 
12
  class FeedbackTransformer:
13
  """
 
259
 
260
  return analysis_text
261
 
262
+ def get_download_data(self, output_format='xlsx'):
263
+ """
264
+ Return the data as bytes for direct download (NEW METHOD).
265
+ """
266
+ if self.transformed_data is None:
267
+ raise ValueError("No transformed data to save")
268
+
269
+ # Create filename with original filename prefix and timestamp
270
+ timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
271
+ prefix = self.original_filename if self.original_filename else 'transformed_feedback'
272
+
273
+ if output_format == 'xlsx':
274
+ filename = f"{prefix}_transformed_{timestamp}.xlsx"
275
+ # Create bytes buffer
276
+ buffer = io.BytesIO()
277
+ self.transformed_data.to_excel(buffer, index=False)
278
+ buffer.seek(0)
279
+ return buffer.getvalue(), filename
280
+ else: # csv
281
+ filename = f"{prefix}_transformed_{timestamp}.csv"
282
+ # Create string buffer and encode to bytes
283
+ buffer = io.StringIO()
284
+ self.transformed_data.to_csv(buffer, index=False)
285
+ return buffer.getvalue().encode('utf-8'), filename
286
+
287
  def save_transformed_data(self, output_format='xlsx'):
288
  """
289
  Save the transformed data and return the file path.
 
405
  text_column, recommendation_column, output_format, analyze_data, selected_columns):
406
  """
407
  Main processing function for Gradio interface.
408
+ Returns both file path and download data for multiple download options.
409
  """
410
  try:
411
  # Extract actual column names from display format
 
450
  if analyze_data:
451
  analysis_result = transformer.analyze_data()
452
 
453
+ # Save transformed data (for regular file download)
454
  output_file = transformer.save_transformed_data(output_format)
455
+
456
+ # Get download data (for direct download button)
457
+ download_data, filename = transformer.get_download_data(output_format)
458
+
459
+ status_msg += f"\n💾 File ready for download: {filename}\n"
460
 
461
+ return status_msg, analysis_result, output_file, (download_data, filename)
462
 
463
  except Exception as e:
464
  error_msg = f"❌ Error: {str(e)}\n\n{traceback.format_exc()}"
465
+ return error_msg, "", None, None
466
+
467
+
468
+ def create_download_link(download_data_tuple):
469
+ """
470
+ Create a direct download link using data URI (NEW FUNCTION).
471
+ """
472
+ if download_data_tuple is None:
473
+ return None
474
+
475
+ download_data, filename = download_data_tuple
476
+
477
+ # Encode data as base64
478
+ b64_data = base64.b64encode(download_data).decode()
479
+
480
+ # Determine MIME type
481
+ if filename.endswith('.xlsx'):
482
+ mime_type = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
483
+ else:
484
+ mime_type = 'text/csv'
485
+
486
+ # Create data URI
487
+ data_uri = f"data:{mime_type};base64,{b64_data}"
488
+
489
+ # Return HTML with download link
490
+ download_html = f"""
491
+ <div style="text-align: center; padding: 20px; border: 2px dashed #007bff; border-radius: 10px; background-color: #f8f9fa;">
492
+ <h3 style="color: #007bff; margin-bottom: 15px;">📥 Download Ready!</h3>
493
+ <a href="{data_uri}" download="{filename}"
494
+ style="display: inline-block; padding: 12px 24px; background-color: #007bff; color: white;
495
+ text-decoration: none; border-radius: 5px; font-weight: bold; font-size: 16px;">
496
+ 📄 Download {filename}
497
+ </a>
498
+ <p style="margin-top: 15px; color: #6c757d; font-size: 14px;">
499
+ Click the button above to download your transformed data file.
500
+ </p>
501
+ </div>
502
+ """
503
+
504
+ return download_html
505
 
506
 
507
  # Create Gradio interface
 
523
  2. Select which original columns to include in the output
524
  3. Configure column prefixes (or use defaults)
525
  4. Click "Transform Data" to process
526
+ 5. Download the transformed file using the download button below
527
  """)
528
 
529
  with gr.Row():
 
607
  label="Data Analysis"
608
  )
609
 
610
+ # Download sections - Multiple options for better compatibility
611
  with gr.Row():
612
  with gr.Column():
613
  gr.Markdown("### �� 5. Download Transformed File")
614
+
615
+ # Primary download method - Direct download link
616
+ download_link = gr.HTML(
617
+ label="Direct Download",
618
+ value="Process a file to generate download link",
619
+ visible=True
620
+ )
621
+
622
+ with gr.Column():
623
+ gr.Markdown("### 📥 Alternative Download")
624
+ # Fallback download method - Traditional file component
625
  output_file = gr.File(
626
+ label="Fallback Download (if direct download doesn't work)",
627
  interactive=False,
628
  visible=True
629
  )
630
 
631
+ # Hidden state to store download data
632
+ download_data_state = gr.State()
633
+
634
  # Event handlers
635
  input_file.change(
636
  fn=get_column_selector,
 
651
  analyze_checkbox,
652
  column_selector
653
  ],
654
+ outputs=[status_output, analysis_output, output_file, download_data_state]
655
+ ).then(
656
+ fn=create_download_link,
657
+ inputs=[download_data_state],
658
+ outputs=[download_link]
659
  )
660
 
661
  # Examples section
 
677
  - Use the numbered column list to easily identify and select columns
678
  - The text and recommendation column names in configuration are now for reference only
679
  - To include them in output, select them using the column checkboxes
680
+ - **Two download options provided**: Try the direct download button first. If it doesn't work in your embedded environment, use the fallback download link.
681
+ - The direct download creates a clickable button that should work better in embedded applications
682
  """)
683
 
684
  # Launch the app