jedick commited on
Commit
30b1c80
·
1 Parent(s): f395a83

Add feedback buttons

Browse files
Files changed (3) hide show
  1. app.py +68 -3
  2. feedback.py +88 -0
  3. models.py +0 -3
app.py CHANGED
@@ -7,16 +7,21 @@ from wiki_data_fetcher import (
7
  get_revisions_behind,
8
  get_random_wikipedia_title,
9
  )
10
- from models import classifier, judge
11
- import logfire
12
- from dotenv import load_dotenv
13
  from contextlib import nullcontext
 
 
 
14
 
15
  # Load API keys
16
  load_dotenv()
17
  # Setup logging with Logfire
18
  logfire.configure()
19
 
 
 
 
 
20
 
21
  def start_parent_span(title: str, number: int, units: str):
22
  """
@@ -419,6 +424,17 @@ with gr.Blocks(title="Noteworthy Differences") as demo:
419
  )
420
  rerun_btn = gr.Button("Rerun Model")
421
 
 
 
 
 
 
 
 
 
 
 
 
422
  # States to store boolean values
423
  heuristic_noteworthy = gr.State()
424
  fewshot_noteworthy = gr.State()
@@ -510,6 +526,55 @@ with gr.Blocks(title="Noteworthy Differences") as demo:
510
  api_name=False,
511
  )
512
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
513
  if __name__ == "__main__":
514
 
515
  # Setup theme without background image
 
7
  get_revisions_behind,
8
  get_random_wikipedia_title,
9
  )
10
+ from feedback import save_feedback_agree, save_feedback_disagree
 
 
11
  from contextlib import nullcontext
12
+ from dotenv import load_dotenv
13
+ import logfire
14
+ import os
15
 
16
  # Load API keys
17
  load_dotenv()
18
  # Setup logging with Logfire
19
  logfire.configure()
20
 
21
+ # Import this after logfire.configure() so we don't get
22
+ # LogfireNotConfiguredWarning: Instrumentation will have no effect
23
+ from models import classifier, judge
24
+
25
 
26
  def start_parent_span(title: str, number: int, units: str):
27
  """
 
424
  )
425
  rerun_btn = gr.Button("Rerun Model")
426
 
427
+ gr.Markdown("### Your feedback")
428
+ feedback_status = gr.Textbox(
429
+ label="",
430
+ lines=1,
431
+ interactive=False,
432
+ visible=True,
433
+ )
434
+ with gr.Row():
435
+ thumbs_up_btn = gr.Button("👍 Agree", variant="primary")
436
+ thumbs_down_btn = gr.Button("👎 Disagree", variant="secondary")
437
+
438
  # States to store boolean values
439
  heuristic_noteworthy = gr.State()
440
  fewshot_noteworthy = gr.State()
 
526
  api_name=False,
527
  )
528
 
529
+ # Feedback button handlers
530
+ thumbs_up_btn.click(
531
+ fn=save_feedback_agree,
532
+ inputs=[
533
+ title_input,
534
+ number_input,
535
+ units_dropdown,
536
+ judge_mode_dropdown,
537
+ old_revision,
538
+ new_revision,
539
+ old_timestamp,
540
+ new_timestamp,
541
+ heuristic_rationale,
542
+ fewshot_rationale,
543
+ judge_reasoning,
544
+ noteworthy_text,
545
+ confidence,
546
+ heuristic_noteworthy,
547
+ fewshot_noteworthy,
548
+ judge_noteworthy,
549
+ ],
550
+ outputs=[feedback_status],
551
+ api_name=False,
552
+ )
553
+
554
+ thumbs_down_btn.click(
555
+ fn=save_feedback_disagree,
556
+ inputs=[
557
+ title_input,
558
+ number_input,
559
+ units_dropdown,
560
+ judge_mode_dropdown,
561
+ old_revision,
562
+ new_revision,
563
+ old_timestamp,
564
+ new_timestamp,
565
+ heuristic_rationale,
566
+ fewshot_rationale,
567
+ judge_reasoning,
568
+ noteworthy_text,
569
+ confidence,
570
+ heuristic_noteworthy,
571
+ fewshot_noteworthy,
572
+ judge_noteworthy,
573
+ ],
574
+ outputs=[feedback_status],
575
+ api_name=False,
576
+ )
577
+
578
  if __name__ == "__main__":
579
 
580
  # Setup theme without background image
feedback.py ADDED
@@ -0,0 +1,88 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from huggingface_hub import HfApi, CommitScheduler
2
+ from datetime import datetime
3
+ from pathlib import Path
4
+ import gradio as gr
5
+ import logfire
6
+ import json
7
+ import os
8
+
9
+ # Set repo ID for Hugging Face dataset
10
+ REPO_ID = "jedick/noteworthy-differences-feedback"
11
+ # Setup user feedback file for uploading to HF dataset
12
+ # https://huggingface.co/spaces/Wauplin/space_to_dataset_saver
13
+ # https://huggingface.co/docs/huggingface_hub/v0.16.3/en/guides/upload#scheduled-uploads
14
+ USER_FEEDBACK_DIR = Path("user_feedback")
15
+ USER_FEEDBACK_DIR.mkdir(parents=True, exist_ok=True)
16
+
17
+
18
+ if gr.NO_RELOAD:
19
+ # Create dataset if one doesn't exist
20
+ if not HfApi().repo_exists(REPO_ID, repo_type="dataset"):
21
+ api.create_repo(REPO_ID, repo_type="dataset")
22
+
23
+ # Initialize commit scheduler if we're running on Hugging Face spaces
24
+ if "SPACE_ID" in os.environ:
25
+ scheduler = CommitScheduler(
26
+ repo_id=REPO_ID,
27
+ repo_type="dataset",
28
+ folder_path=USER_FEEDBACK_DIR,
29
+ path_in_repo="data",
30
+ )
31
+
32
+
33
+ def save_feedback(*args, feedback_value: str) -> None:
34
+ """
35
+ Save complete app state and user feedback to a
36
+ JSON Lines file for upload to a Hugging Face dataset.
37
+ """
38
+ # Assign dict keys to positional arguments
39
+ keys = [
40
+ "title_input",
41
+ "number_input",
42
+ "units_dropdown",
43
+ "judge_mode_dropdown",
44
+ "old_revision",
45
+ "new_revision",
46
+ "old_timestamp",
47
+ "new_timestamp",
48
+ "heuristic_rationale",
49
+ "fewshot_rationale",
50
+ "judge_reasoning",
51
+ "noteworthy_text",
52
+ "confidence",
53
+ "heuristic_noteworthy",
54
+ "fewshot_noteworthy",
55
+ "judge_noteworthy",
56
+ ]
57
+ feedback_dict = dict(zip(keys, args))
58
+ # Add feedback value
59
+ feedback_dict["feedback"] = feedback_value
60
+ # Save feedback to file
61
+ feedback_file = f"train-{datetime.now().isoformat()}.json"
62
+ feedback_path = USER_FEEDBACK_DIR / feedback_file
63
+ with feedback_path.open("a") as f:
64
+ f.write(json.dumps(feedback_dict))
65
+ f.write("\n")
66
+ gr.Success(f"Saved your feedback: {feedback_value}", duration=2, title="Thank you!")
67
+
68
+
69
+ @logfire.instrument("Save feedback: agree")
70
+ def save_feedback_agree(*args) -> None:
71
+ """Wrapper to save feedback with 'agree' value."""
72
+ # Schedule feedback for commit if we're running on Hugging Face spaces
73
+ if "SPACE_ID" in os.environ:
74
+ # Use a thread lock to avoid concurrent writes from different users
75
+ with scheduler.lock:
76
+ save_feedback(*args, feedback_value="agree")
77
+ else:
78
+ save_feedback(*args, feedback_value="agree")
79
+
80
+
81
+ @logfire.instrument("Save feedback: disagree")
82
+ def save_feedback_disagree(*args) -> None:
83
+ """Wrapper to save feedback with 'disagree' value."""
84
+ if "SPACE_ID" in os.environ:
85
+ with scheduler.lock:
86
+ save_feedback(*args, feedback_value="disagree")
87
+ else:
88
+ save_feedback(*args, feedback_value="disagree")
models.py CHANGED
@@ -16,9 +16,6 @@ import logfire
16
  # Load API keys
17
  load_dotenv()
18
 
19
- # Setup Logfire
20
- logfire.configure()
21
-
22
  # This wraps Google Gen AI client calls
23
  # to capture prompts, responses, and metadata
24
  logfire.instrument_google_genai()
 
16
  # Load API keys
17
  load_dotenv()
18
 
 
 
 
19
  # This wraps Google Gen AI client calls
20
  # to capture prompts, responses, and metadata
21
  logfire.instrument_google_genai()