yassine123Z commited on
Commit
6b05e4d
Β·
verified Β·
1 Parent(s): 30da262

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +308 -64
app.py CHANGED
@@ -377,116 +377,360 @@ def compare_models_fixed(hf_model_url, file):
377
  # ==================================================
378
  # 🎨 Improved Light & Clean Gradio UI
379
  # ==================================================
 
 
 
380
  custom_css = """
 
 
381
  .gradio-container {
382
- font-family: 'Poppins', sans-serif;
383
- background-color: #f9fafc !important;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
384
  }
385
- footer {display:none !important;}
386
 
 
387
  .gr-button-primary {
388
- background: linear-gradient(90deg, #4a6cf7, #6a8ff7) !important;
389
  color: white !important;
 
390
  border-radius: 10px !important;
391
- height: 42px !important;
392
  font-weight: 600 !important;
 
 
 
393
  }
 
394
  .gr-button-primary:hover {
395
- background: linear-gradient(90deg, #5c7df7, #7b9ef7) !important;
 
 
 
 
 
396
  }
397
 
398
- input, textarea {
 
 
 
399
  border-radius: 10px !important;
400
- border: 1px solid #d1d5db !important;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
401
  background: white !important;
 
402
  }
403
 
 
404
  label {
405
  font-weight: 600 !important;
 
 
 
 
 
 
 
406
  color: #1f2937 !important;
 
 
 
 
 
 
 
 
 
407
  }
408
 
409
- h1, h2, h3, h4 {
410
- color: #1e293b !important;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
411
  }
412
  """
413
 
414
- with gr.Blocks(css=custom_css, theme=gr.themes.Soft(), title="🌍 Carbon Mapper Dashboard") as main_ui:
415
- # Header
 
416
  gr.HTML("""
417
- <div style="background: linear-gradient(90deg, #4a6cf7, #6a8ff7);
418
- color: white; padding: 16px 25px; border-radius: 12px;
419
- display: flex; align-items: center; justify-content: space-between;">
420
- <div>
421
- <h1 style="margin:0;font-size:24px;">🌿 Carbon Transaction Mapper</h1>
422
- <p style="margin:0;font-size:14px;opacity:0.9;">Classify, review and improve your sustainability data.</p>
 
 
 
 
423
  </div>
424
- <div style="opacity:0.9;font-size:12px;">v2.1 | SetFit + FastAPI</div>
425
  </div>
426
  """)
427
 
428
- # Tabs
429
  with gr.Tab("πŸ”Ή Single Transaction"):
 
 
 
 
 
 
 
430
  with gr.Row():
431
  with gr.Column(scale=1):
432
- gr.Markdown("### πŸ” Classify a Transaction")
433
  text_input = gr.Textbox(
434
- label="Enter Transaction Description",
435
- placeholder="Ex: Hotel booking for conference in Paris",
436
- lines=3
437
  )
438
- btn_submit = gr.Button("πŸš€ Predict", variant="primary")
 
439
  with gr.Column(scale=1):
440
- cat1_out = gr.Textbox(label="Predicted Category 1", interactive=False)
441
- cat2_out = gr.Textbox(label="Predicted Category 2", interactive=False)
442
- score_out = gr.Number(label="Confidence", interactive=False)
 
 
443
  btn_submit.click(fn=classify_single, inputs=text_input, outputs=[cat1_out, cat2_out, score_out])
444
 
445
- with gr.Tab("πŸ“‚ Batch Review & Correction"):
446
- gr.Markdown("""
447
- ### πŸ“‹ Batch Review
448
- Upload your transactions and review predicted categories.
449
- You can directly edit incorrect classifications in the table below.
 
450
  """)
451
- csv_input = gr.File(label="πŸ“ Upload CSV file", file_types=[".csv"])
452
- btn_process = gr.Button("βš™οΈ Process File", variant="primary")
453
- process_status = gr.Markdown("")
454
- review_table = gr.DataFrame(label="Editable Review Table", interactive=True, wrap=True)
455
- btn_save = gr.Button("πŸ’Ύ Save Corrections", variant="primary")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
456
  save_status = gr.Markdown()
457
- btn_download_corrected = gr.File(label="πŸ“₯ Download Corrected File")
458
- btn_download_training = gr.File(label="πŸ“₯ Training Data Only")
459
- btn_process.click(fn=map_csv_for_review, inputs=csv_input, outputs=[review_table, process_status])
460
- btn_save.click(fn=save_batch_corrections, inputs=review_table,
461
- outputs=[save_status, btn_download_corrected, btn_download_training])
462
-
463
- with gr.Tab("πŸ“Š All Corrections History"):
464
- gr.Markdown("### 🧾 Saved Corrections History")
465
- btn_refresh = gr.Button("πŸ”„ Refresh List")
466
- corrections_table = gr.DataFrame(label="All Corrections", interactive=False)
467
- btn_export_all = gr.Button("πŸ“€ Export All Corrections", variant="primary")
468
- export_all_file = gr.File(label="πŸ“₯ Download Export")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
469
  export_status = gr.Markdown()
 
 
470
  btn_refresh.click(fn=show_corrections, outputs=corrections_table)
471
  btn_export_all.click(fn=export_all_corrections, outputs=[export_all_file, export_status])
472
 
473
  with gr.Tab("πŸ§ͺ Model Comparison"):
474
- gr.Markdown("### βš–οΈ Compare Models on a Test File")
475
- hf_model_url = gr.Textbox(
476
- label="Enter HuggingFace model ID",
477
- placeholder="e.g. sentence-transformers/all-MiniLM-L6-v2"
478
- )
479
- compare_file = gr.File(label="Upload CSV for Comparison", file_types=[".csv"])
480
- compare_btn = gr.Button("πŸ”¬ Compare", variant="primary")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
481
  compare_summary = gr.Markdown()
482
- compare_results = gr.DataFrame(label="Model Comparison Results")
483
- compare_btn.click(fn=compare_models_fixed,
484
- inputs=[hf_model_url, compare_file],
485
- outputs=[compare_summary, compare_results])
486
-
487
- gr.Markdown("<br><center><small>Built by Yassine 🧠 | SetFit + Gradio + FastAPI</small></center>")
488
-
 
 
 
 
489
 
 
 
 
 
 
 
 
 
 
 
 
 
490
  # ==================================================
491
  # 🌐 Mount Gradio App
492
  # ==================================================
 
377
  # ==================================================
378
  # 🎨 Improved Light & Clean Gradio UI
379
  # ==================================================
380
+ # ==================================================
381
+ # 🎨 Modern & Attractive Gradio UI
382
+ # ==================================================
383
  custom_css = """
384
+ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');
385
+
386
  .gradio-container {
387
+ font-family: 'Inter', sans-serif !important;
388
+ background: linear-gradient(135deg, #f5f7fa 0%, #e9ecef 100%) !important;
389
+ }
390
+
391
+ footer {display: none !important;}
392
+
393
+ /* Header Styling */
394
+ .app-header {
395
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
396
+ padding: 28px 32px;
397
+ border-radius: 16px;
398
+ box-shadow: 0 8px 32px rgba(102, 126, 234, 0.25);
399
+ margin-bottom: 24px;
400
+ }
401
+
402
+ .app-header h1 {
403
+ font-size: 28px;
404
+ font-weight: 700;
405
+ margin: 0 0 8px 0;
406
+ color: white !important;
407
+ }
408
+
409
+ .app-header p {
410
+ font-size: 15px;
411
+ margin: 0;
412
+ opacity: 0.95;
413
+ color: white;
414
+ }
415
+
416
+ /* Tab Styling */
417
+ .tab-nav button {
418
+ font-weight: 600 !important;
419
+ font-size: 14px !important;
420
+ padding: 12px 20px !important;
421
+ border-radius: 10px 10px 0 0 !important;
422
+ transition: all 0.3s ease !important;
423
+ }
424
+
425
+ .tab-nav button[aria-selected="true"] {
426
+ background: white !important;
427
+ box-shadow: 0 -2px 8px rgba(0,0,0,0.05) !important;
428
+ }
429
+
430
+ /* Card Styling */
431
+ .gr-box, .gr-form, .gr-panel {
432
+ border-radius: 12px !important;
433
+ border: 1px solid #e5e7eb !important;
434
+ background: white !important;
435
+ box-shadow: 0 2px 8px rgba(0,0,0,0.04) !important;
436
+ padding: 20px !important;
437
  }
 
438
 
439
+ /* Button Styling */
440
  .gr-button-primary {
441
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important;
442
  color: white !important;
443
+ border: none !important;
444
  border-radius: 10px !important;
445
+ height: 44px !important;
446
  font-weight: 600 !important;
447
+ font-size: 14px !important;
448
+ box-shadow: 0 4px 12px rgba(102, 126, 234, 0.3) !important;
449
+ transition: all 0.3s ease !important;
450
  }
451
+
452
  .gr-button-primary:hover {
453
+ transform: translateY(-2px) !important;
454
+ box-shadow: 0 6px 20px rgba(102, 126, 234, 0.4) !important;
455
+ }
456
+
457
+ .gr-button-primary:active {
458
+ transform: translateY(0) !important;
459
  }
460
 
461
+ .gr-button-secondary {
462
+ background: white !important;
463
+ color: #667eea !important;
464
+ border: 2px solid #667eea !important;
465
  border-radius: 10px !important;
466
+ height: 44px !important;
467
+ font-weight: 600 !important;
468
+ transition: all 0.3s ease !important;
469
+ }
470
+
471
+ .gr-button-secondary:hover {
472
+ background: #f5f7ff !important;
473
+ }
474
+
475
+ /* Input Styling */
476
+ input, textarea, .gr-input {
477
+ border-radius: 10px !important;
478
+ border: 2px solid #e5e7eb !important;
479
+ background: #fafbfc !important;
480
+ font-size: 14px !important;
481
+ transition: all 0.3s ease !important;
482
+ }
483
+
484
+ input:focus, textarea:focus, .gr-input:focus {
485
+ border-color: #667eea !important;
486
  background: white !important;
487
+ box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1) !important;
488
  }
489
 
490
+ /* Label Styling */
491
  label {
492
  font-weight: 600 !important;
493
+ color: #374151 !important;
494
+ font-size: 14px !important;
495
+ margin-bottom: 8px !important;
496
+ }
497
+
498
+ /* Markdown Section Headers */
499
+ .prose h3 {
500
  color: #1f2937 !important;
501
+ font-weight: 700 !important;
502
+ font-size: 18px !important;
503
+ margin-bottom: 12px !important;
504
+ }
505
+
506
+ /* Table Styling */
507
+ .gr-dataframe {
508
+ border-radius: 12px !important;
509
+ overflow: hidden !important;
510
  }
511
 
512
+ /* File Upload Styling */
513
+ .gr-file {
514
+ border: 2px dashed #d1d5db !important;
515
+ border-radius: 12px !important;
516
+ background: #fafbfc !important;
517
+ transition: all 0.3s ease !important;
518
+ }
519
+
520
+ .gr-file:hover {
521
+ border-color: #667eea !important;
522
+ background: #f5f7ff !important;
523
+ }
524
+
525
+ /* Info Box */
526
+ .info-box {
527
+ background: linear-gradient(135deg, #e0e7ff 0%, #f5f3ff 100%);
528
+ border-left: 4px solid #667eea;
529
+ padding: 16px 20px;
530
+ border-radius: 10px;
531
+ margin: 16px 0;
532
+ }
533
+
534
+ /* Status Messages */
535
+ .status-success {
536
+ background: #d1fae5;
537
+ color: #065f46;
538
+ padding: 12px 16px;
539
+ border-radius: 8px;
540
+ border-left: 4px solid #10b981;
541
+ }
542
+
543
+ .status-error {
544
+ background: #fee2e2;
545
+ color: #991b1b;
546
+ padding: 12px 16px;
547
+ border-radius: 8px;
548
+ border-left: 4px solid #ef4444;
549
+ }
550
+
551
+ /* Icon Styling */
552
+ .icon-emoji {
553
+ font-size: 24px;
554
+ margin-right: 8px;
555
+ }
556
+
557
+ /* Responsive Design */
558
+ @media (max-width: 768px) {
559
+ .app-header h1 {
560
+ font-size: 22px;
561
+ }
562
+ .app-header p {
563
+ font-size: 13px;
564
+ }
565
  }
566
  """
567
 
568
+ with gr.Blocks(css=custom_css, theme=gr.themes.Soft(primary_hue="indigo"), title="🌍 Carbon Mapper Dashboard") as main_ui:
569
+
570
+ # Modern Header
571
  gr.HTML("""
572
+ <div class="app-header">
573
+ <div style="display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap;">
574
+ <div>
575
+ <h1>🌿 Carbon Transaction Mapper</h1>
576
+ <p>Intelligent classification and review for sustainability data powered by AI</p>
577
+ </div>
578
+ <div style="text-align: right; opacity: 0.9;">
579
+ <div style="font-size: 12px; font-weight: 500;">VERSION 2.1</div>
580
+ <div style="font-size: 11px; margin-top: 4px;">SetFit β€’ FastAPI</div>
581
+ </div>
582
  </div>
 
583
  </div>
584
  """)
585
 
586
+ # Tabs with modern styling
587
  with gr.Tab("πŸ”Ή Single Transaction"):
588
+ gr.HTML("""
589
+ <div class="info-box">
590
+ <strong>πŸ’‘ Quick Classification</strong><br>
591
+ Enter a transaction description to get instant AI-powered category predictions
592
+ </div>
593
+ """)
594
+
595
  with gr.Row():
596
  with gr.Column(scale=1):
 
597
  text_input = gr.Textbox(
598
+ label="Transaction Description",
599
+ placeholder="Example: Hotel booking for business conference in Paris",
600
+ lines=4
601
  )
602
+ btn_submit = gr.Button("πŸš€ Classify Transaction", variant="primary", size="lg")
603
+
604
  with gr.Column(scale=1):
605
+ gr.Markdown("#### πŸ“Š Prediction Results")
606
+ cat1_out = gr.Textbox(label="Primary Category", interactive=False)
607
+ cat2_out = gr.Textbox(label="Secondary Category", interactive=False)
608
+ score_out = gr.Number(label="Confidence Score", interactive=False, precision=2)
609
+
610
  btn_submit.click(fn=classify_single, inputs=text_input, outputs=[cat1_out, cat2_out, score_out])
611
 
612
+ with gr.Tab("πŸ“‚ Batch Review"):
613
+ gr.HTML("""
614
+ <div class="info-box">
615
+ <strong>πŸ“‹ Batch Processing & Review</strong><br>
616
+ Upload your CSV file to classify multiple transactions at once. Review and correct predictions directly in the table.
617
+ </div>
618
  """)
619
+
620
+ with gr.Row():
621
+ with gr.Column(scale=1):
622
+ csv_input = gr.File(
623
+ label="πŸ“ Upload CSV File",
624
+ file_types=[".csv"],
625
+ file_count="single"
626
+ )
627
+ btn_process = gr.Button("βš™οΈ Process & Review", variant="primary", size="lg")
628
+
629
+ process_status = gr.Markdown()
630
+
631
+ gr.Markdown("### πŸ“ Review & Edit Predictions")
632
+ review_table = gr.DataFrame(
633
+ label="Editable Classification Table",
634
+ interactive=True,
635
+ wrap=True,
636
+ height=400
637
+ )
638
+
639
+ with gr.Row():
640
+ btn_save = gr.Button("πŸ’Ύ Save All Corrections", variant="primary", size="lg")
641
+
642
  save_status = gr.Markdown()
643
+
644
+ with gr.Row():
645
+ with gr.Column(scale=1):
646
+ btn_download_corrected = gr.File(label="πŸ“₯ Corrected Dataset")
647
+ with gr.Column(scale=1):
648
+ btn_download_training = gr.File(label="πŸ“₯ Training Data Export")
649
+
650
+ btn_process.click(
651
+ fn=map_csv_for_review,
652
+ inputs=csv_input,
653
+ outputs=[review_table, process_status]
654
+ )
655
+ btn_save.click(
656
+ fn=save_batch_corrections,
657
+ inputs=review_table,
658
+ outputs=[save_status, btn_download_corrected, btn_download_training]
659
+ )
660
+
661
+ with gr.Tab("πŸ“Š Corrections History"):
662
+ gr.HTML("""
663
+ <div class="info-box">
664
+ <strong>🧾 Historical Corrections</strong><br>
665
+ View and export all your saved corrections for model retraining and analysis
666
+ </div>
667
+ """)
668
+
669
+ btn_refresh = gr.Button("πŸ”„ Refresh History", variant="secondary", size="lg")
670
+ corrections_table = gr.DataFrame(
671
+ label="Complete Corrections Log",
672
+ interactive=False,
673
+ wrap=True,
674
+ height=400
675
+ )
676
+
677
+ with gr.Row():
678
+ btn_export_all = gr.Button("πŸ“€ Export All Data", variant="primary", size="lg")
679
+
680
  export_status = gr.Markdown()
681
+ export_all_file = gr.File(label="πŸ“₯ Download Complete Export")
682
+
683
  btn_refresh.click(fn=show_corrections, outputs=corrections_table)
684
  btn_export_all.click(fn=export_all_corrections, outputs=[export_all_file, export_status])
685
 
686
  with gr.Tab("πŸ§ͺ Model Comparison"):
687
+ gr.HTML("""
688
+ <div class="info-box">
689
+ <strong>βš–οΈ A/B Testing</strong><br>
690
+ Compare your current model against alternative models from HuggingFace
691
+ </div>
692
+ """)
693
+
694
+ with gr.Row():
695
+ with gr.Column(scale=2):
696
+ hf_model_url = gr.Textbox(
697
+ label="HuggingFace Model ID",
698
+ placeholder="e.g., sentence-transformers/all-MiniLM-L6-v2",
699
+ info="Enter the full model path from HuggingFace Hub"
700
+ )
701
+ with gr.Column(scale=2):
702
+ compare_file = gr.File(
703
+ label="Test Dataset (CSV)",
704
+ file_types=[".csv"]
705
+ )
706
+
707
+ compare_btn = gr.Button("πŸ”¬ Run Comparison", variant="primary", size="lg")
708
+
709
  compare_summary = gr.Markdown()
710
+ compare_results = gr.DataFrame(
711
+ label="Detailed Comparison Results",
712
+ wrap=True,
713
+ height=400
714
+ )
715
+
716
+ compare_btn.click(
717
+ fn=compare_models_fixed,
718
+ inputs=[hf_model_url, compare_file],
719
+ outputs=[compare_summary, compare_results]
720
+ )
721
 
722
+ # Footer
723
+ gr.HTML("""
724
+ <div style="text-align: center; padding: 24px 0; margin-top: 32px; border-top: 1px solid #e5e7eb;">
725
+ <p style="color: #6b7280; font-size: 14px; margin: 0;">
726
+ Built with ❀️ by <strong>Yassine</strong> | Powered by SetFit, Gradio & FastAPI
727
+ </p>
728
+ <p style="color: #9ca3af; font-size: 12px; margin-top: 8px;">
729
+ 🌱 Making sustainability data smarter, one transaction at a time
730
+ </p>
731
+ </div>
732
+ """)
733
+
734
  # ==================================================
735
  # 🌐 Mount Gradio App
736
  # ==================================================