jedick commited on
Commit
8d79272
·
1 Parent(s): 3c02ce2

Make parent span for app runs

Browse files
Files changed (1) hide show
  1. app.py +87 -22
app.py CHANGED
@@ -10,20 +10,37 @@ from wiki_data_fetcher import (
10
  from models import classifier, judge
11
  import logfire
12
  from dotenv import load_dotenv
 
13
 
14
  # Load API keys
15
  load_dotenv()
16
  # Setup logging with Logfire
17
  logfire.configure()
18
 
19
- # If running a standalone Gradio app via `demo.launch()` within a script,
20
- # Logfire's auto-instrumentation for FastAPI is often automatically handled
21
- # if installed. If mounting within a separate FastAPI app, use:
22
- # logfire.instrument_fastapi(app)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
 
24
 
25
  @logfire.instrument("Step 1: Fetch current revision")
26
- def fetch_current_revision(title: str):
27
  """
28
  Fetch current revision of a Wikipedia article and return its introduction.
29
 
@@ -69,15 +86,22 @@ def fetch_current_revision(title: str):
69
  return None, None
70
 
71
 
 
 
 
 
 
 
 
72
  @logfire.instrument("Step 2: Fetch previous revision")
73
- def fetch_previous_revision(title: str, unit: str, number: int, new_revision: str):
74
  """
75
  Fetch previous revision of a Wikipedia article and return its introduction.
76
 
77
  Args:
78
  title: Wikipedia article title
79
- unit: "revisions" or "days"
80
  number: Number of revisions or days behind
 
81
 
82
  Returns:
83
  Tuple of (introduction, timestamp)
@@ -89,15 +113,15 @@ def fetch_previous_revision(title: str, unit: str, number: int, new_revision: st
89
  return None, None
90
 
91
  try:
92
- # Get previous revision based on unit
93
- if unit == "revisions":
94
  json_data = get_previous_revisions(title, revisions=number)
95
  revision_info = extract_revision_info(json_data, revnum=number)
96
- else: # unit == "days"
97
  revision_info = get_revision_from_age(title, age_days=number)
98
 
99
  if not revision_info.get("revid"):
100
- error_msg = f"Error: Could not find revision {number} {'revisions' if unit == 'revisions' else 'days'} behind for '{title}'."
101
  raise gr.Error(error_msg, print_exception=False)
102
  return None, None
103
 
@@ -111,7 +135,7 @@ def fetch_previous_revision(title: str, unit: str, number: int, new_revision: st
111
  introduction = f"Error: Could not retrieve introduction for previous revision (revid: {revid})"
112
 
113
  # Get revisions_behind
114
- if unit == "revisions":
115
  revisions_behind = revision_info["revnum"]
116
  else:
117
  revisions_behind = get_revisions_behind(title, revid)
@@ -170,13 +194,23 @@ def run_classifier(old_revision: str, new_revision: str, prompt_style: str):
170
  return noteworthy, rationale
171
 
172
 
 
 
 
 
 
173
  @logfire.instrument("Step 3a: Run heuristic classifier")
174
- def run_heuristic_classifier(old_revision: str, new_revision: str):
175
  return run_classifier(old_revision, new_revision, prompt_style="heuristic")
176
 
177
 
 
 
 
 
 
178
  @logfire.instrument("Step 3b: Run few-shot classifier")
179
- def run_fewshot_classifier(old_revision: str, new_revision: str):
180
  return run_classifier(old_revision, new_revision, prompt_style="few-shot")
181
 
182
 
@@ -205,7 +239,6 @@ def compute_confidence(
205
  return "Questionable"
206
 
207
 
208
- @logfire.instrument("Step 4: Run judge")
209
  def run_judge(
210
  old_revision: str,
211
  new_revision: str,
@@ -214,6 +247,29 @@ def run_judge(
214
  heuristic_rationale: str,
215
  fewshot_rationale: str,
216
  judge_mode: str,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
217
  ):
218
  """
219
  Run judge on the revisions and classifiers' rationales.
@@ -295,7 +351,7 @@ with gr.Blocks(title="Noteworthy Differences") as demo:
295
  label="Wikipedia Page Title", placeholder="e.g., Albert Einstein", value=""
296
  )
297
  number_input = gr.Number(label="Number", value=50, minimum=0, precision=0)
298
- unit_dropdown = gr.Dropdown(
299
  choices=["revisions", "days"], value="revisions", label="Unit"
300
  )
301
  judge_mode_dropdown = gr.Dropdown(
@@ -367,6 +423,8 @@ with gr.Blocks(title="Noteworthy Differences") as demo:
367
  heuristic_noteworthy = gr.State()
368
  fewshot_noteworthy = gr.State()
369
  judge_noteworthy = gr.State()
 
 
370
 
371
  random_btn.click(
372
  fn=get_random_wikipedia_title,
@@ -383,24 +441,29 @@ with gr.Blocks(title="Noteworthy Differences") as demo:
383
  inputs=None,
384
  outputs=[new_revision, new_timestamp],
385
  api_name=False,
 
 
 
 
 
386
  ).then(
387
  fn=fetch_current_revision,
388
- inputs=[title_input],
389
  outputs=[new_revision, new_timestamp],
390
  api_name=False,
391
  ).then(
392
  fn=fetch_previous_revision,
393
- inputs=[title_input, unit_dropdown, number_input, new_revision],
394
  outputs=[old_revision, old_timestamp],
395
  api_name=False,
396
  ).then(
397
  fn=run_heuristic_classifier,
398
- inputs=[old_revision, new_revision],
399
  outputs=[heuristic_noteworthy, heuristic_rationale],
400
  api_name=False,
401
  ).then(
402
  fn=run_fewshot_classifier,
403
- inputs=[old_revision, new_revision],
404
  outputs=[fewshot_noteworthy, fewshot_rationale],
405
  api_name=False,
406
  ).then(
@@ -413,6 +476,7 @@ with gr.Blocks(title="Noteworthy Differences") as demo:
413
  heuristic_rationale,
414
  fewshot_rationale,
415
  judge_mode_dropdown,
 
416
  ],
417
  outputs=[judge_noteworthy, noteworthy_text, judge_reasoning, confidence],
418
  api_name=False,
@@ -422,12 +486,12 @@ with gr.Blocks(title="Noteworthy Differences") as demo:
422
  gr.on(
423
  triggers=[rerun_btn.click],
424
  fn=run_heuristic_classifier,
425
- inputs=[old_revision, new_revision],
426
  outputs=[heuristic_noteworthy, heuristic_rationale],
427
  api_name=False,
428
  ).then(
429
  fn=run_fewshot_classifier,
430
- inputs=[old_revision, new_revision],
431
  outputs=[fewshot_noteworthy, fewshot_rationale],
432
  api_name=False,
433
  ).then(
@@ -440,6 +504,7 @@ with gr.Blocks(title="Noteworthy Differences") as demo:
440
  heuristic_rationale,
441
  fewshot_rationale,
442
  judge_mode_dropdown,
 
443
  ],
444
  outputs=[judge_noteworthy, noteworthy_text, judge_reasoning, confidence],
445
  api_name=False,
 
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
+ """
23
+ Start a parent span and return the context for propagation to children.
24
+ See https://logfire.pydantic.dev/docs/how-to-guides/distributed-tracing/#manual-context-propagation
25
+ """
26
+ span_name = f"{title} - {number} {units}"
27
+ with logfire.span(span_name) as span:
28
+ span.__enter__()
29
+ context = logfire.get_context()
30
+ return context
31
+
32
+
33
+ def fetch_current_revision(title: str, context=None):
34
+ """
35
+ Wrapper to run _fetch_current_revision in provided Logfire context.
36
+ We use this to minimize indentation in the wrapped function.
37
+ """
38
+ with logfire.attach_context(context) if context else nullcontext():
39
+ return _fetch_current_revision(title)
40
 
41
 
42
  @logfire.instrument("Step 1: Fetch current revision")
43
+ def _fetch_current_revision(title: str):
44
  """
45
  Fetch current revision of a Wikipedia article and return its introduction.
46
 
 
86
  return None, None
87
 
88
 
89
+ def fetch_previous_revision(
90
+ title: str, number: int, units: str, new_revision: str, context=None
91
+ ):
92
+ with logfire.attach_context(context) if context else nullcontext():
93
+ return _fetch_previous_revision(title, number, units, new_revision)
94
+
95
+
96
  @logfire.instrument("Step 2: Fetch previous revision")
97
+ def _fetch_previous_revision(title: str, number: int, units: str, new_revision: str):
98
  """
99
  Fetch previous revision of a Wikipedia article and return its introduction.
100
 
101
  Args:
102
  title: Wikipedia article title
 
103
  number: Number of revisions or days behind
104
+ units: "revisions" or "days"
105
 
106
  Returns:
107
  Tuple of (introduction, timestamp)
 
113
  return None, None
114
 
115
  try:
116
+ # Get previous revision based on units
117
+ if units == "revisions":
118
  json_data = get_previous_revisions(title, revisions=number)
119
  revision_info = extract_revision_info(json_data, revnum=number)
120
+ else: # units == "days"
121
  revision_info = get_revision_from_age(title, age_days=number)
122
 
123
  if not revision_info.get("revid"):
124
+ error_msg = f"Error: Could not find revision {number} {'revisions' if units == 'revisions' else 'days'} behind for '{title}'."
125
  raise gr.Error(error_msg, print_exception=False)
126
  return None, None
127
 
 
135
  introduction = f"Error: Could not retrieve introduction for previous revision (revid: {revid})"
136
 
137
  # Get revisions_behind
138
+ if units == "revisions":
139
  revisions_behind = revision_info["revnum"]
140
  else:
141
  revisions_behind = get_revisions_behind(title, revid)
 
194
  return noteworthy, rationale
195
 
196
 
197
+ def run_heuristic_classifier(old_revision: str, new_revision: str, context=None):
198
+ with logfire.attach_context(context) if context else nullcontext():
199
+ return _run_heuristic_classifier(old_revision, new_revision)
200
+
201
+
202
  @logfire.instrument("Step 3a: Run heuristic classifier")
203
+ def _run_heuristic_classifier(old_revision: str, new_revision: str):
204
  return run_classifier(old_revision, new_revision, prompt_style="heuristic")
205
 
206
 
207
+ def run_fewshot_classifier(old_revision: str, new_revision: str, context=None):
208
+ with logfire.attach_context(context) if context else nullcontext():
209
+ return _run_fewshot_classifier(old_revision, new_revision)
210
+
211
+
212
  @logfire.instrument("Step 3b: Run few-shot classifier")
213
+ def _run_fewshot_classifier(old_revision: str, new_revision: str):
214
  return run_classifier(old_revision, new_revision, prompt_style="few-shot")
215
 
216
 
 
239
  return "Questionable"
240
 
241
 
 
242
  def run_judge(
243
  old_revision: str,
244
  new_revision: str,
 
247
  heuristic_rationale: str,
248
  fewshot_rationale: str,
249
  judge_mode: str,
250
+ context=None,
251
+ ):
252
+ with logfire.attach_context(context) if context else nullcontext():
253
+ return _run_judge(
254
+ old_revision,
255
+ new_revision,
256
+ heuristic_noteworthy,
257
+ heuristic_noteworthy,
258
+ heuristic_rationale,
259
+ fewshot_rationale,
260
+ judge_mode,
261
+ )
262
+
263
+
264
+ @logfire.instrument("Step 4: Run judge")
265
+ def _run_judge(
266
+ old_revision: str,
267
+ new_revision: str,
268
+ heuristic_noteworthy: bool,
269
+ fewshot_noteworthy: bool,
270
+ heuristic_rationale: str,
271
+ fewshot_rationale: str,
272
+ judge_mode: str,
273
  ):
274
  """
275
  Run judge on the revisions and classifiers' rationales.
 
351
  label="Wikipedia Page Title", placeholder="e.g., Albert Einstein", value=""
352
  )
353
  number_input = gr.Number(label="Number", value=50, minimum=0, precision=0)
354
+ units_dropdown = gr.Dropdown(
355
  choices=["revisions", "days"], value="revisions", label="Unit"
356
  )
357
  judge_mode_dropdown = gr.Dropdown(
 
423
  heuristic_noteworthy = gr.State()
424
  fewshot_noteworthy = gr.State()
425
  judge_noteworthy = gr.State()
426
+ # State to store Logfire context
427
+ context = gr.State()
428
 
429
  random_btn.click(
430
  fn=get_random_wikipedia_title,
 
441
  inputs=None,
442
  outputs=[new_revision, new_timestamp],
443
  api_name=False,
444
+ ).then(
445
+ # Initialize Logfire context
446
+ fn=start_parent_span,
447
+ inputs=[title_input, number_input, units_dropdown],
448
+ outputs=context,
449
  ).then(
450
  fn=fetch_current_revision,
451
+ inputs=[title_input, context],
452
  outputs=[new_revision, new_timestamp],
453
  api_name=False,
454
  ).then(
455
  fn=fetch_previous_revision,
456
+ inputs=[title_input, number_input, units_dropdown, new_revision, context],
457
  outputs=[old_revision, old_timestamp],
458
  api_name=False,
459
  ).then(
460
  fn=run_heuristic_classifier,
461
+ inputs=[old_revision, new_revision, context],
462
  outputs=[heuristic_noteworthy, heuristic_rationale],
463
  api_name=False,
464
  ).then(
465
  fn=run_fewshot_classifier,
466
+ inputs=[old_revision, new_revision, context],
467
  outputs=[fewshot_noteworthy, fewshot_rationale],
468
  api_name=False,
469
  ).then(
 
476
  heuristic_rationale,
477
  fewshot_rationale,
478
  judge_mode_dropdown,
479
+ context,
480
  ],
481
  outputs=[judge_noteworthy, noteworthy_text, judge_reasoning, confidence],
482
  api_name=False,
 
486
  gr.on(
487
  triggers=[rerun_btn.click],
488
  fn=run_heuristic_classifier,
489
+ inputs=[old_revision, new_revision, context],
490
  outputs=[heuristic_noteworthy, heuristic_rationale],
491
  api_name=False,
492
  ).then(
493
  fn=run_fewshot_classifier,
494
+ inputs=[old_revision, new_revision, context],
495
  outputs=[fewshot_noteworthy, fewshot_rationale],
496
  api_name=False,
497
  ).then(
 
504
  heuristic_rationale,
505
  fewshot_rationale,
506
  judge_mode_dropdown,
507
+ context,
508
  ],
509
  outputs=[judge_noteworthy, noteworthy_text, judge_reasoning, confidence],
510
  api_name=False,