AdnanElAssadi commited on
Commit
eade391
·
verified ·
1 Parent(s): 4872c01

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +122 -217
app.py CHANGED
@@ -9,21 +9,20 @@ def create_reranking_interface(task_data):
9
  results = {"task_name": task_data["task_name"], "task_type": "reranking", "annotations": []}
10
  completed_samples = {s["id"]: False for s in samples}
11
 
12
- # Track the current ordering of documents
13
- current_document_order = gr.State([])
14
 
15
- def save_ranking(sample_id, doc_order):
16
  """Save the current document ordering as rankings."""
17
  try:
18
- if not doc_order:
19
  return "⚠️ No document ordering found", f"Progress: {sum(completed_samples.values())}/{len(samples)}"
20
 
21
- # Convert document positions to rankings
22
- # The first document (position 0) gets rank 1, etc.
23
  rankings = []
24
- for i in range(len(doc_order)):
25
- doc_idx = doc_order.index(i)
26
- rankings.append(doc_idx + 1) # Convert to 1-based ranks
27
 
28
  # Store this annotation in memory
29
  existing_idx = next((i for i, a in enumerate(results["annotations"]) if a["sample_id"] == sample_id), None)
@@ -53,159 +52,19 @@ def create_reranking_interface(task_data):
53
  # Return specific error message
54
  return f"Error: {str(e)}", f"Progress: {sum(completed_samples.values())}/{len(samples)}"
55
 
56
- def initialize_documents(sample_id):
57
- """Initialize the document order and content for a sample."""
58
- sample = next((s for s in samples if s["id"] == sample_id), None)
59
- if not sample:
60
- return [], "", "Query not found", f"Progress: {sum(completed_samples.values())}/{len(samples)}"
61
-
62
- # Get the documents for this sample
63
- docs = sample["candidates"]
64
-
65
- # Initialize the document order (0, 1, 2, ..., n-1)
66
- doc_order = list(range(len(docs)))
67
-
68
- # Check if this sample has already been annotated to restore ordering
69
- existing_annotation = next((a for a in results["annotations"] if a["sample_id"] == sample_id), None)
70
- if existing_annotation and "rankings" in existing_annotation:
71
- # Convert rankings back to positions
72
- # If document 0 has rank 3, it should be in position 2
73
- sorted_positions = []
74
- for i in range(len(existing_annotation["rankings"])):
75
- rank = existing_annotation["rankings"][i]
76
- sorted_positions.append((i, rank))
77
-
78
- # Sort by rank (ascending)
79
- sorted_positions.sort(key=lambda x: x[1])
80
-
81
- # Extract the original indices in their ranked order
82
- doc_order = [pos[0] for pos in sorted_positions]
83
-
84
- # Current sample query
85
- query = sample["query"]
86
-
87
- # Status message
88
- status = f"Viewing query {samples.index(sample) + 1} of {len(samples)}"
89
- if completed_samples[sample_id]:
90
- status += " (already completed)"
91
-
92
- return doc_order, query, status, f"Progress: {sum(completed_samples.values())}/{len(samples)}"
93
-
94
- def move_document(doc_order, doc_idx, direction):
95
- """Move a document up or down in the order."""
96
- if not doc_order:
97
- return doc_order
98
-
99
- # Create a copy of the order to avoid reference issues
100
- new_order = doc_order.copy()
101
-
102
- # Find the current position of the document in the order
103
- current_pos = new_order.index(doc_idx)
104
-
105
- # Calculate the new position
106
- if direction == "up" and current_pos > 0:
107
  # Swap with the document above
108
- new_order[current_pos], new_order[current_pos - 1] = new_order[current_pos - 1], new_order[current_pos]
109
- elif direction == "down" and current_pos < len(new_order) - 1:
110
- # Swap with the document below
111
- new_order[current_pos], new_order[current_pos + 1] = new_order[current_pos + 1], new_order[current_pos]
112
-
113
- return new_order
114
 
115
- def render_documents(doc_order, sample_id):
116
- """Render the documents in the specified order."""
117
- sample = next((s for s in samples if s["id"] == sample_id), None)
118
- if not sample or not doc_order:
119
- return gr.HTML.update(value="<p>No documents to display</p>")
120
-
121
- docs = sample["candidates"]
122
-
123
- # Build HTML for the document list
124
- html = "<div class='document-list'>"
125
-
126
- for pos, doc_idx in enumerate(doc_order):
127
- if doc_idx < len(docs):
128
- doc_text = docs[doc_idx]
129
-
130
- # Calculate the rank (position + 1)
131
- rank = pos + 1
132
-
133
- # Create a container for each document with buttons and rank
134
- html += f"""
135
- <div class='document-item' id='doc-{doc_idx}'>
136
- <div class='document-controls'>
137
- <div class='rank-display'>Rank: {rank}</div>
138
- <button class='move-up-btn' onclick='moveDocument({doc_idx}, "up")'>↑ Move Up</button>
139
- <button class='move-down-btn' onclick='moveDocument({doc_idx}, "down")'>↓ Move Down</button>
140
- </div>
141
- <div class='document-content'>
142
- <p><strong>Document {doc_idx + 1}:</strong> {doc_text}</p>
143
- </div>
144
- </div>
145
- """
146
-
147
- html += "</div>"
148
-
149
- # Add custom CSS
150
- html += """
151
- <style>
152
- .document-list {
153
- display: flex;
154
- flex-direction: column;
155
- gap: 10px;
156
- }
157
- .document-item {
158
- border: 1px solid #ddd;
159
- border-radius: 8px;
160
- padding: 15px;
161
- background-color: #f9f9f9;
162
- display: flex;
163
- flex-direction: column;
164
- }
165
- .document-controls {
166
- display: flex;
167
- align-items: center;
168
- gap: 10px;
169
- margin-bottom: 10px;
170
- }
171
- .rank-display {
172
- font-weight: bold;
173
- min-width: 80px;
174
- }
175
- .document-content {
176
- padding: 5px;
177
- background-color: white;
178
- border-radius: 4px;
179
- }
180
- button {
181
- padding: 5px 10px;
182
- border-radius: 4px;
183
- border: 1px solid #ccc;
184
- cursor: pointer;
185
- }
186
- .move-up-btn {
187
- background-color: #e0f7fa;
188
- }
189
- .move-down-btn {
190
- background-color: #fff3e0;
191
- }
192
- </style>
193
- """
194
-
195
- # Add JavaScript to handle button clicks
196
- html += """
197
- <script>
198
- function moveDocument(docIdx, direction) {
199
- // Call the Python function via Gradio's API
200
- const event = new CustomEvent('move-document', {
201
- detail: { docIdx: docIdx, direction: direction }
202
- });
203
- document.dispatchEvent(event);
204
- }
205
- </script>
206
- """
207
-
208
- return gr.HTML.update(value=html)
209
 
210
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
211
  gr.Markdown(f"# {task_data['task_name']} - Human Reranking Evaluation")
@@ -238,15 +97,76 @@ def create_reranking_interface(task_data):
238
 
239
  gr.Markdown("## Documents (Arrange in order of relevance, most relevant at top):")
240
 
241
- # Container to display documents in their current order
242
- document_list = gr.HTML()
243
 
244
- # For Gradio's event handling, we need actual buttons
245
- # These are invisible and triggered by JavaScript
246
- with gr.Row(visible=False):
247
- up_btn = gr.Button("Up")
248
- down_btn = gr.Button("Down")
249
- doc_index = gr.Number(0, label="Document Index")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
250
 
251
  with gr.Row():
252
  prev_btn = gr.Button("← Previous Query", size="sm")
@@ -255,82 +175,67 @@ def create_reranking_interface(task_data):
255
 
256
  save_btn = gr.Button("💾 Save All Results", variant="secondary")
257
 
258
- # Initialize the document order for the first sample
259
- doc_order, query_val, status_val, progress_val = initialize_documents(samples[0]["id"])
260
- current_document_order.value = doc_order
261
- query_text.value = query_val
262
  status_box.value = status_val
263
  progress_text.value = progress_val
264
 
265
- # Render the documents in their initial order
266
- document_list.value = render_documents(doc_order, samples[0]["id"]).value
267
-
268
- # Connect events for up/down buttons (these are triggered by JavaScript)
269
- def doc_move_handler(doc_idx, direction, current_order, sample_id):
270
- new_order = move_document(current_order, doc_idx, direction)
271
- html_update = render_documents(new_order, sample_id)
272
- return new_order, html_update
273
-
274
- up_btn.click(
275
- doc_move_handler,
276
- inputs=[doc_index, gr.Textbox(value="up"), current_document_order, current_sample_id],
277
- outputs=[current_document_order, document_list]
278
- )
279
-
280
- down_btn.click(
281
- doc_move_handler,
282
- inputs=[doc_index, gr.Textbox(value="down"), current_document_order, current_sample_id],
283
- outputs=[current_document_order, document_list]
284
- )
285
-
286
- # Load a sample and update the interface
287
- def load_sample(sample_id):
288
- doc_order, query_val, status_val, progress_val = initialize_documents(sample_id)
289
- html_update = render_documents(doc_order, sample_id)
290
- return doc_order, query_val, html_update, status_val, progress_val
291
-
292
- # Navigation events
293
- def nav_sample(current_id, direction):
294
- """Navigate to the previous or next sample."""
295
  current_sample = next((s for s in samples if s["id"] == current_id), None)
296
  if not current_sample:
297
  return current_id
298
 
299
  current_idx = samples.index(current_sample)
 
 
 
 
 
 
 
 
 
300
 
301
- if direction == "next" and current_idx < len(samples) - 1:
 
302
  next_sample = samples[current_idx + 1]
303
  return next_sample["id"]
304
- elif direction == "prev" and current_idx > 0:
305
- prev_sample = samples[current_idx - 1]
306
- return prev_sample["id"]
307
-
308
  return current_id
309
 
310
- next_btn.click(
311
- lambda id: nav_sample(id, "next"),
 
312
  inputs=[current_sample_id],
313
  outputs=[current_sample_id]
314
  ).then(
315
- load_sample,
316
  inputs=[current_sample_id],
317
- outputs=[current_document_order, query_text, document_list, status_box, progress_text]
 
 
 
 
318
  )
319
 
320
- prev_btn.click(
321
- lambda id: nav_sample(id, "prev"),
322
  inputs=[current_sample_id],
323
  outputs=[current_sample_id]
324
  ).then(
325
- load_sample,
326
  inputs=[current_sample_id],
327
- outputs=[current_document_order, query_text, document_list, status_box, progress_text]
 
 
 
 
328
  )
329
 
330
- # Submit rankings
331
  submit_btn.click(
332
  save_ranking,
333
- inputs=[current_sample_id, current_document_order],
334
  outputs=[status_box, progress_text]
335
  )
336
 
 
9
  results = {"task_name": task_data["task_name"], "task_type": "reranking", "annotations": []}
10
  completed_samples = {s["id"]: False for s in samples}
11
 
12
+ # Store the current document order for the active sample
13
+ current_order = []
14
 
15
+ def save_ranking(sample_id):
16
  """Save the current document ordering as rankings."""
17
  try:
18
+ if not current_order:
19
  return "⚠️ No document ordering found", f"Progress: {sum(completed_samples.values())}/{len(samples)}"
20
 
21
+ # Convert document positions to rankings (position in list -> document's rank)
22
+ # First document (position 0) gets rank 1, etc.
23
  rankings = []
24
+ for i, doc_idx in enumerate(current_order):
25
+ rankings.append(i + 1) # Convert to 1-based ranks
 
26
 
27
  # Store this annotation in memory
28
  existing_idx = next((i for i, a in enumerate(results["annotations"]) if a["sample_id"] == sample_id), None)
 
52
  # Return specific error message
53
  return f"Error: {str(e)}", f"Progress: {sum(completed_samples.values())}/{len(samples)}"
54
 
55
+ def move_document_up(idx):
56
+ nonlocal current_order
57
+ if idx > 0:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58
  # Swap with the document above
59
+ current_order[idx], current_order[idx-1] = current_order[idx-1], current_order[idx]
60
+ return gr.update(value=f"Moved document up: {idx}")
 
 
 
 
61
 
62
+ def move_document_down(idx):
63
+ nonlocal current_order
64
+ if idx < len(current_order) - 1:
65
+ # Swap with the document below
66
+ current_order[idx], current_order[idx+1] = current_order[idx+1], current_order[idx]
67
+ return gr.update(value=f"Moved document down: {idx}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
68
 
69
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
70
  gr.Markdown(f"# {task_data['task_name']} - Human Reranking Evaluation")
 
97
 
98
  gr.Markdown("## Documents (Arrange in order of relevance, most relevant at top):")
99
 
100
+ # Create simple document list with move up/down buttons
101
+ document_containers = []
102
 
103
+ # Function to initialize the document list for a sample
104
+ def initialize_document_list(sample_id):
105
+ nonlocal current_order
106
+
107
+ sample = next((s for s in samples if s["id"] == sample_id), None)
108
+ if not sample:
109
+ return "Query not found", f"Progress: {sum(completed_samples.values())}/{len(samples)}"
110
+
111
+ # Get the documents for this sample
112
+ docs = sample["candidates"]
113
+
114
+ # Initialize document order (0, 1, 2, ..., n-1)
115
+ current_order = list(range(len(docs)))
116
+
117
+ # Check if this sample has already been annotated to restore ordering
118
+ existing_annotation = next((a for a in results["annotations"] if a["sample_id"] == sample_id), None)
119
+ if existing_annotation and "rankings" in existing_annotation:
120
+ # Sort documents based on previous rankings
121
+ # This is a simplified version that just keeps the original order for now
122
+ pass
123
+
124
+ # Update UI
125
+ for i, doc_idx in enumerate(current_order):
126
+ if i < len(document_containers) and doc_idx < len(docs):
127
+ document_containers[i].value = f"Document {doc_idx+1} (Rank: {i+1}): {docs[doc_idx]}"
128
+
129
+ # Status message
130
+ status = f"Viewing query {samples.index(sample) + 1} of {len(samples)}"
131
+ if completed_samples[sample_id]:
132
+ status += " (already completed)"
133
+
134
+ return status, f"Progress: {sum(completed_samples.values())}/{len(samples)}"
135
+
136
+ # Create document display containers with up/down buttons
137
+ with gr.Column():
138
+ for i in range(10): # Assuming max 10 documents per sample
139
+ with gr.Group():
140
+ with gr.Row():
141
+ doc_text = gr.Textbox(label=f"Document {i+1}", interactive=False)
142
+ document_containers.append(doc_text)
143
+
144
+ with gr.Row():
145
+ up_btn = gr.Button(f"⬆️ Move Up", size="sm")
146
+ down_btn = gr.Button(f"⬇️ Move Down", size="sm")
147
+
148
+ # Connect the up/down buttons
149
+ up_btn.click(
150
+ lambda idx=i: move_document_up(idx),
151
+ inputs=[],
152
+ outputs=[status_box]
153
+ ).then(
154
+ lambda: [gr.update(value=f"Document {current_order[j]+1} (Rank: {j+1}): {samples[0]['candidates'][current_order[j]]}")
155
+ for j in range(len(current_order))],
156
+ inputs=[],
157
+ outputs=document_containers[:len(current_order)]
158
+ )
159
+
160
+ down_btn.click(
161
+ lambda idx=i: move_document_down(idx),
162
+ inputs=[],
163
+ outputs=[status_box]
164
+ ).then(
165
+ lambda: [gr.update(value=f"Document {current_order[j]+1} (Rank: {j+1}): {samples[0]['candidates'][current_order[j]]}")
166
+ for j in range(len(current_order))],
167
+ inputs=[],
168
+ outputs=document_containers[:len(current_order)]
169
+ )
170
 
171
  with gr.Row():
172
  prev_btn = gr.Button("← Previous Query", size="sm")
 
175
 
176
  save_btn = gr.Button("💾 Save All Results", variant="secondary")
177
 
178
+ # Initialize the document list for the first sample
179
+ status_val, progress_val = initialize_document_list(samples[0]["id"])
 
 
180
  status_box.value = status_val
181
  progress_text.value = progress_val
182
 
183
+ # Navigation functions
184
+ def nav_to_prev(current_id):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
185
  current_sample = next((s for s in samples if s["id"] == current_id), None)
186
  if not current_sample:
187
  return current_id
188
 
189
  current_idx = samples.index(current_sample)
190
+ if current_idx > 0:
191
+ prev_sample = samples[current_idx - 1]
192
+ return prev_sample["id"]
193
+ return current_id
194
+
195
+ def nav_to_next(current_id):
196
+ current_sample = next((s for s in samples if s["id"] == current_id), None)
197
+ if not current_sample:
198
+ return current_id
199
 
200
+ current_idx = samples.index(current_sample)
201
+ if current_idx < len(samples) - 1:
202
  next_sample = samples[current_idx + 1]
203
  return next_sample["id"]
 
 
 
 
204
  return current_id
205
 
206
+ # Connect navigation buttons
207
+ prev_btn.click(
208
+ nav_to_prev,
209
  inputs=[current_sample_id],
210
  outputs=[current_sample_id]
211
  ).then(
212
+ lambda id: initialize_document_list(id),
213
  inputs=[current_sample_id],
214
+ outputs=[status_box, progress_text]
215
+ ).then(
216
+ lambda id: next((s["query"] for s in samples if s["id"] == id), ""),
217
+ inputs=[current_sample_id],
218
+ outputs=[query_text]
219
  )
220
 
221
+ next_btn.click(
222
+ nav_to_next,
223
  inputs=[current_sample_id],
224
  outputs=[current_sample_id]
225
  ).then(
226
+ lambda id: initialize_document_list(id),
227
  inputs=[current_sample_id],
228
+ outputs=[status_box, progress_text]
229
+ ).then(
230
+ lambda id: next((s["query"] for s in samples if s["id"] == id), ""),
231
+ inputs=[current_sample_id],
232
+ outputs=[query_text]
233
  )
234
 
235
+ # Submit button
236
  submit_btn.click(
237
  save_ranking,
238
+ inputs=[current_sample_id],
239
  outputs=[status_box, progress_text]
240
  )
241