Spaces:
Sleeping
Sleeping
Update app.py
Browse files
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: '
|
| 383 |
-
background
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 384 |
}
|
| 385 |
-
footer {display:none !important;}
|
| 386 |
|
|
|
|
| 387 |
.gr-button-primary {
|
| 388 |
-
background: linear-gradient(
|
| 389 |
color: white !important;
|
|
|
|
| 390 |
border-radius: 10px !important;
|
| 391 |
-
height:
|
| 392 |
font-weight: 600 !important;
|
|
|
|
|
|
|
|
|
|
| 393 |
}
|
|
|
|
| 394 |
.gr-button-primary:hover {
|
| 395 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 396 |
}
|
| 397 |
|
| 398 |
-
|
|
|
|
|
|
|
|
|
|
| 399 |
border-radius: 10px !important;
|
| 400 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 401 |
background: white !important;
|
|
|
|
| 402 |
}
|
| 403 |
|
|
|
|
| 404 |
label {
|
| 405 |
font-weight: 600 !important;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 406 |
color: #1f2937 !important;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 407 |
}
|
| 408 |
|
| 409 |
-
|
| 410 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 411 |
}
|
| 412 |
"""
|
| 413 |
|
| 414 |
-
with gr.Blocks(css=custom_css, theme=gr.themes.Soft(), title="π Carbon Mapper Dashboard") as main_ui:
|
| 415 |
-
|
|
|
|
| 416 |
gr.HTML("""
|
| 417 |
-
<div
|
| 418 |
-
|
| 419 |
-
|
| 420 |
-
|
| 421 |
-
|
| 422 |
-
<
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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="
|
| 435 |
-
placeholder="
|
| 436 |
-
lines=
|
| 437 |
)
|
| 438 |
-
btn_submit = gr.Button("π
|
|
|
|
| 439 |
with gr.Column(scale=1):
|
| 440 |
-
|
| 441 |
-
|
| 442 |
-
|
|
|
|
|
|
|
| 443 |
btn_submit.click(fn=classify_single, inputs=text_input, outputs=[cat1_out, cat2_out, score_out])
|
| 444 |
|
| 445 |
-
with gr.Tab("π Batch Review
|
| 446 |
-
gr.
|
| 447 |
-
|
| 448 |
-
|
| 449 |
-
|
|
|
|
| 450 |
""")
|
| 451 |
-
|
| 452 |
-
|
| 453 |
-
|
| 454 |
-
|
| 455 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 456 |
save_status = gr.Markdown()
|
| 457 |
-
|
| 458 |
-
|
| 459 |
-
|
| 460 |
-
|
| 461 |
-
|
| 462 |
-
|
| 463 |
-
|
| 464 |
-
|
| 465 |
-
|
| 466 |
-
|
| 467 |
-
|
| 468 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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.
|
| 475 |
-
|
| 476 |
-
|
| 477 |
-
|
| 478 |
-
|
| 479 |
-
|
| 480 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 481 |
compare_summary = gr.Markdown()
|
| 482 |
-
compare_results = gr.DataFrame(
|
| 483 |
-
|
| 484 |
-
|
| 485 |
-
|
| 486 |
-
|
| 487 |
-
|
| 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 |
# ==================================================
|