AdnanElAssadi commited on
Commit
06960f4
·
verified ·
1 Parent(s): 7242363

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +101 -111
app.py CHANGED
@@ -440,46 +440,6 @@ def create_reranking_interface(task_data):
440
 
441
  return status, progress
442
 
443
- def load_sample(sample_id):
444
- """Load a specific sample into the interface."""
445
- sample = next((s for s in samples if s["id"] == sample_id), None)
446
- if not sample:
447
- return [query_text.value] + [d.value for d in doc_containers] + [""] * len(ranking_inputs) + [""] * len(validation_indicators) + [sample_id, progress_text.value, status_box.value]
448
-
449
- # Update query
450
- new_query = sample["query"]
451
-
452
- # Update documents
453
- new_docs = []
454
- for i, doc in enumerate(sample["candidates"]):
455
- if i < len(doc_containers):
456
- new_docs.append(doc)
457
-
458
- # Initialize rankings
459
- new_rankings = [""] * len(ranking_inputs)
460
-
461
- # Check if this sample has already been annotated
462
- existing_annotation = next((a for a in results["annotations"] if a["sample_id"] == sample_id), None)
463
- if existing_annotation:
464
- # Restore previous rankings
465
- for i, rank in enumerate(existing_annotation["rankings"]):
466
- if i < len(new_rankings) and rank is not None:
467
- new_rankings[i] = str(rank)
468
-
469
- # Update progress
470
- current_idx = samples.index(sample)
471
- new_progress = f"Progress: {sum(completed_samples.values())}/{len(samples)}"
472
-
473
- new_status = f"Viewing query {current_idx + 1} of {len(samples)}"
474
- if completed_samples[sample_id]:
475
- new_status += " (already completed)"
476
-
477
- # Initialize validation indicators
478
- validation_results = validate_rankings(*new_rankings)
479
- validation_indicators_values = validation_results[:-1] # Remove validity flag
480
-
481
- return [new_query] + new_docs + new_rankings + validation_indicators_values + [sample_id, new_progress, new_status]
482
-
483
  def auto_save_and_navigate(direction, current_id, auto_save, *rankings):
484
  """Save rankings if auto-save is enabled, then navigate."""
485
  # Extract rankings (remove validation indicators)
@@ -539,113 +499,143 @@ def create_reranking_interface(task_data):
539
  except Exception as e:
540
  return f"Error saving results: {str(e)}"
541
 
542
- # Define optimized functions for the quick ranking buttons
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
543
  def assign_sequential_ranks():
544
  """Assign sequential rankings (1,2,3...) to all documents."""
545
  sequential_ranks = [str(i+1) for i in range(len(samples[0]["candidates"]))]
546
- # Return ranks plus a success message
547
- return sequential_ranks + ["✅ Applied sequential ranking"]
548
 
549
  def assign_reverse_ranks():
550
  """Assign reverse rankings (n,n-1...) to all documents."""
551
  n = len(samples[0]["candidates"])
552
  reverse_ranks = [str(n-i) for i in range(n)]
553
- # Return ranks plus a success message
554
- return reverse_ranks + ["✅ Applied reverse ranking"]
555
 
556
  def clear_rankings():
557
  """Clear all rankings."""
558
  empty_ranks = [""] * len(samples[0]["candidates"])
559
- # Return empty ranks plus a success message
560
- return empty_ranks + ["✅ Cleared all rankings"]
561
-
562
- # Connect quick ranking buttons - add status message output
 
 
 
 
 
563
  sequential_btn.click(
564
  fn=assign_sequential_ranks,
565
  inputs=None,
566
- outputs=ranking_inputs + [status_box]
 
 
 
 
567
  )
568
 
569
  reverse_btn.click(
570
  fn=assign_reverse_ranks,
571
  inputs=None,
572
- outputs=ranking_inputs + [status_box]
 
 
 
 
573
  )
574
 
575
  clear_btn.click(
576
  fn=clear_rankings,
577
  inputs=None,
578
- outputs=ranking_inputs + [status_box]
579
- )
580
-
581
- # Optimize validation - reduce redundant validations
582
- # Instead of connecting validation to each ranking input change,
583
- # add a "Validate Rankings" button that runs validation on demand
584
-
585
- with gr.Row():
586
- validate_btn = gr.Button("Validate Rankings", variant="secondary")
587
-
588
- # Connect validate button to the right function
589
- validate_btn.click(
590
- fn=lambda *rankings: validate_rankings(*rankings)[:-1] + ["Validation complete"],
591
- inputs=ranking_inputs,
592
- outputs=validation_indicators + [status_box]
593
- )
594
-
595
- # Add a simpler validation for individual inputs that doesn't cascade to all inputs
596
- def validate_single_input(rank, index):
597
- """Lightweight validation for a single input."""
598
- if rank is None or rank == "":
599
- return '<span style="color: #dc3545;">⚠️</span>'
600
- else:
601
- return f'<span style="color: #28a745;">✓ {rank}</span>'
602
-
603
- # Connect simpler validation to each input
604
- for i, ranking in enumerate(ranking_inputs):
605
- ranking.change(
606
- fn=lambda r, idx=i: validate_single_input(r, idx),
607
- inputs=[ranking],
608
- outputs=[validation_indicators[i]]
609
- )
610
-
611
- # Wire up events (Gradio 3.x syntax)
612
- submit_btn.click(
613
- fn=submit_rankings,
614
- inputs=ranking_inputs + [current_sample_id],
615
- outputs=[status_box, progress_text]
616
  )
617
 
618
- # Auto-save and navigate events
619
- def handle_next(current_id, auto_save, *rankings):
620
- # First, handle auto-save
621
- new_id, status, progress = auto_save_and_navigate("next", current_id, auto_save, *rankings)
622
- # Then, load the new sample
623
- outputs = load_sample(new_id)
624
- # Add the status and progress
625
- outputs[-2] = progress if status else outputs[-2]
626
- outputs[-1] = status if status else outputs[-1]
627
- return outputs
628
-
629
- def handle_prev(current_id, auto_save, *rankings):
630
- # First, handle auto-save
631
- new_id, status, progress = auto_save_and_navigate("prev", current_id, auto_save, *rankings)
632
- # Then, load the new sample
633
- outputs = load_sample(new_id)
634
- # Add the status and progress
635
- outputs[-2] = progress if status else outputs[-2]
636
- outputs[-1] = status if status else outputs[-1]
637
- return outputs
638
-
639
- # Connect navigation with Gradio 3.x syntax
640
  next_btn.click(
641
  fn=handle_next,
642
  inputs=[current_sample_id, auto_save_toggle] + ranking_inputs,
 
 
 
 
643
  outputs=[query_text] + doc_containers + ranking_inputs + validation_indicators + [current_sample_id, progress_text, status_box]
644
  )
645
 
646
  prev_btn.click(
647
  fn=handle_prev,
648
  inputs=[current_sample_id, auto_save_toggle] + ranking_inputs,
 
 
 
 
649
  outputs=[query_text] + doc_containers + ranking_inputs + validation_indicators + [current_sample_id, progress_text, status_box]
650
  )
651
 
 
440
 
441
  return status, progress
442
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
443
  def auto_save_and_navigate(direction, current_id, auto_save, *rankings):
444
  """Save rankings if auto-save is enabled, then navigate."""
445
  # Extract rankings (remove validation indicators)
 
499
  except Exception as e:
500
  return f"Error saving results: {str(e)}"
501
 
502
+ # Optimize the navigation functions to reduce unnecessary updates
503
+ def handle_next(current_id, auto_save, *rankings):
504
+ """Optimized handler for next query navigation."""
505
+ # First, handle auto-save (only if needed)
506
+ new_id, status, progress = auto_save_and_navigate("next", current_id, auto_save, *rankings)
507
+
508
+ # Return the new sample ID for a more efficient update
509
+ # The load_sample function will handle all UI updates in one batch
510
+ return new_id
511
+
512
+ def handle_prev(current_id, auto_save, *rankings):
513
+ """Optimized handler for previous query navigation."""
514
+ # First, handle auto-save (only if needed)
515
+ new_id, status, progress = auto_save_and_navigate("prev", current_id, auto_save, *rankings)
516
+
517
+ # Return the new sample ID for a more efficient update
518
+ # The load_sample function will handle all UI updates in one batch
519
+ return new_id
520
+
521
+ # Optimize the load_sample function to handle all UI updates efficiently
522
+ def load_sample(sample_id):
523
+ """Load a specific sample into the interface."""
524
+ # Clear all validation indicators first for a cleaner transition
525
+ blank_validations = [""] * len(validation_indicators)
526
+
527
+ # Find the sample data
528
+ sample = next((s for s in samples if s["id"] == sample_id), None)
529
+ if not sample:
530
+ return [query_text.value] + [d.value for d in doc_containers] + [""] * len(ranking_inputs) + blank_validations + [sample_id, progress_text.value, status_box.value]
531
+
532
+ # Update query
533
+ new_query = sample["query"]
534
+
535
+ # Update documents
536
+ new_docs = []
537
+ for i, doc in enumerate(sample["candidates"]):
538
+ if i < len(doc_containers):
539
+ new_docs.append(doc)
540
+
541
+ # Initialize rankings
542
+ new_rankings = [""] * len(ranking_inputs)
543
+
544
+ # Check if this sample has already been annotated
545
+ existing_annotation = next((a for a in results["annotations"] if a["sample_id"] == sample_id), None)
546
+ if existing_annotation:
547
+ # Restore previous rankings
548
+ for i, rank in enumerate(existing_annotation["rankings"]):
549
+ if i < len(new_rankings) and rank is not None:
550
+ new_rankings[i] = str(rank)
551
+
552
+ # Update progress
553
+ current_idx = samples.index(sample)
554
+ new_progress = f"Progress: {sum(completed_samples.values())}/{len(samples)}"
555
+
556
+ new_status = f"Viewing query {current_idx + 1} of {len(samples)}"
557
+ if completed_samples[sample_id]:
558
+ new_status += " (already completed)"
559
+
560
+ # Initialize validation indicators (but don't run validation until needed)
561
+ # This improves load time
562
+
563
+ return [new_query] + new_docs + new_rankings + blank_validations + [sample_id, new_progress, new_status]
564
+
565
+ # Optimize the quick ranking functions for better performance
566
  def assign_sequential_ranks():
567
  """Assign sequential rankings (1,2,3...) to all documents."""
568
  sequential_ranks = [str(i+1) for i in range(len(samples[0]["candidates"]))]
569
+ # Return ranks only - validation will be done separately for better performance
570
+ return sequential_ranks
571
 
572
  def assign_reverse_ranks():
573
  """Assign reverse rankings (n,n-1...) to all documents."""
574
  n = len(samples[0]["candidates"])
575
  reverse_ranks = [str(n-i) for i in range(n)]
576
+ # Return ranks only - validation will be done separately for better performance
577
+ return reverse_ranks
578
 
579
  def clear_rankings():
580
  """Clear all rankings."""
581
  empty_ranks = [""] * len(samples[0]["candidates"])
582
+ # Return empty ranks only - validation will be done separately for better performance
583
+ return empty_ranks
584
+
585
+ # Add a function to update status after quick ranking operations
586
+ def update_status_after_ranking(operation_name):
587
+ """Update status box after a ranking operation."""
588
+ return f"✅ {operation_name} applied successfully"
589
+
590
+ # Connect quick ranking buttons with more efficient handling
591
  sequential_btn.click(
592
  fn=assign_sequential_ranks,
593
  inputs=None,
594
+ outputs=ranking_inputs
595
+ ).then(
596
+ fn=lambda: update_status_after_ranking("Sequential ranking"),
597
+ inputs=None,
598
+ outputs=[status_box]
599
  )
600
 
601
  reverse_btn.click(
602
  fn=assign_reverse_ranks,
603
  inputs=None,
604
+ outputs=ranking_inputs
605
+ ).then(
606
+ fn=lambda: update_status_after_ranking("Reverse ranking"),
607
+ inputs=None,
608
+ outputs=[status_box]
609
  )
610
 
611
  clear_btn.click(
612
  fn=clear_rankings,
613
  inputs=None,
614
+ outputs=ranking_inputs
615
+ ).then(
616
+ fn=lambda: update_status_after_ranking("Rankings cleared"),
617
+ inputs=None,
618
+ outputs=[status_box]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
619
  )
620
 
621
+ # Connect navigation with more efficient data handling
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
622
  next_btn.click(
623
  fn=handle_next,
624
  inputs=[current_sample_id, auto_save_toggle] + ranking_inputs,
625
+ outputs=[current_sample_id] # Only update the sample ID
626
+ ).then(
627
+ fn=load_sample, # Then load the sample with all UI updates in one batch
628
+ inputs=[current_sample_id],
629
  outputs=[query_text] + doc_containers + ranking_inputs + validation_indicators + [current_sample_id, progress_text, status_box]
630
  )
631
 
632
  prev_btn.click(
633
  fn=handle_prev,
634
  inputs=[current_sample_id, auto_save_toggle] + ranking_inputs,
635
+ outputs=[current_sample_id] # Only update the sample ID
636
+ ).then(
637
+ fn=load_sample, # Then load the sample with all UI updates in one batch
638
+ inputs=[current_sample_id],
639
  outputs=[query_text] + doc_containers + ranking_inputs + validation_indicators + [current_sample_id, progress_text, status_box]
640
  )
641