kerojohan commited on
Commit
2efea6e
·
1 Parent(s): 146f9cc

Show pipeline progress in Gradio UI

Browse files
Files changed (2) hide show
  1. app.py +10 -2
  2. bat_tracker/pipeline.py +18 -3
app.py CHANGED
@@ -24,7 +24,8 @@ APP_DESCRIPTION = (
24
  def _prepare_config(config_file: str | None, work_dir: Path) -> Path:
25
  cfg = load_config(config_file)
26
  cfg.setdefault("output", {})
27
- cfg["output"]["progress_enabled"] = False
 
28
 
29
  config_path = work_dir / "space_config.yaml"
30
  with config_path.open("w", encoding="utf-8") as handle:
@@ -50,7 +51,7 @@ def _copy_input_file(src: str, dst_dir: Path) -> Path:
50
  return dst_path
51
 
52
 
53
- def process_video(video_file: str | None, config_file: str | None):
54
  if not video_file:
55
  raise gr.Error("Debes subir un video de entrada.")
56
 
@@ -62,12 +63,19 @@ def process_video(video_file: str | None, config_file: str | None):
62
  work_dir.mkdir(parents=True, exist_ok=True)
63
 
64
  try:
 
65
  input_path = _copy_input_file(video_file, work_dir)
66
  config_path = _prepare_config(config_file, work_dir)
 
 
 
 
 
67
  meta = run_pipeline(
68
  input_video=str(input_path),
69
  output_dir=str(output_dir),
70
  config_path=str(config_path),
 
71
  )
72
 
73
  outputs = meta.get("outputs", {})
 
24
  def _prepare_config(config_file: str | None, work_dir: Path) -> Path:
25
  cfg = load_config(config_file)
26
  cfg.setdefault("output", {})
27
+ cfg["output"]["progress_enabled"] = True
28
+ cfg["output"]["progress_step_percent"] = 2
29
 
30
  config_path = work_dir / "space_config.yaml"
31
  with config_path.open("w", encoding="utf-8") as handle:
 
51
  return dst_path
52
 
53
 
54
+ def process_video(video_file: str | None, config_file: str | None, progress=gr.Progress()):
55
  if not video_file:
56
  raise gr.Error("Debes subir un video de entrada.")
57
 
 
63
  work_dir.mkdir(parents=True, exist_ok=True)
64
 
65
  try:
66
+ progress(0, desc="Preparando ejecución")
67
  input_path = _copy_input_file(video_file, work_dir)
68
  config_path = _prepare_config(config_file, work_dir)
69
+
70
+ def on_pipeline_progress(pct: int, detail: str | None) -> None:
71
+ description = detail or "Procesando"
72
+ progress(min(max(pct / 100.0, 0.0), 1.0), desc=description)
73
+
74
  meta = run_pipeline(
75
  input_video=str(input_path),
76
  output_dir=str(output_dir),
77
  config_path=str(config_path),
78
+ progress_callback=on_pipeline_progress,
79
  )
80
 
81
  outputs = meta.get("outputs", {})
bat_tracker/pipeline.py CHANGED
@@ -9,7 +9,7 @@ from math import ceil
9
  from math import hypot
10
  from pathlib import Path
11
  from statistics import mean
12
- from typing import Dict, List
13
 
14
  import cv2
15
  import numpy as np
@@ -207,12 +207,19 @@ class TemporalBurstGate:
207
 
208
 
209
  class ProgressReporter:
210
- def __init__(self, enabled: bool, step_percent: int, stages: list[tuple[str, float]]):
 
 
 
 
 
 
211
  self.enabled = bool(enabled) and bool(stages)
212
  self.step_percent = max(1, min(100, int(step_percent)))
213
  self._next_threshold = self.step_percent
214
  self._last_reported = 0
215
  self._current_stage = ""
 
216
 
217
  total_weight = sum(max(0.0, float(weight)) for _, weight in stages)
218
  if total_weight <= 0:
@@ -252,6 +259,8 @@ class ProgressReporter:
252
  self._emit(pct, detail=detail)
253
 
254
  def _emit(self, pct: int, detail: str | None = None) -> None:
 
 
255
  if pct < self._next_threshold:
256
  return
257
  self._last_reported = pct
@@ -644,7 +653,12 @@ def _export_track_clips(
644
  return clip_paths
645
 
646
 
647
- def run_pipeline(input_video: str, output_dir: str, config_path: str | None = None) -> Dict:
 
 
 
 
 
648
  cfg = load_config(config_path)
649
  execution_plan = build_execution_plan(cfg)
650
  execution_cfg = cfg.get("execution", {})
@@ -681,6 +695,7 @@ def run_pipeline(input_video: str, output_dir: str, config_path: str | None = No
681
  ("exports_core", 12.0),
682
  ("track_clips", 10.0 if export_track_clips_enabled else 0.0),
683
  ],
 
684
  )
685
 
686
  progress.start_stage("background")
 
9
  from math import hypot
10
  from pathlib import Path
11
  from statistics import mean
12
+ from typing import Callable, Dict, List
13
 
14
  import cv2
15
  import numpy as np
 
207
 
208
 
209
  class ProgressReporter:
210
+ def __init__(
211
+ self,
212
+ enabled: bool,
213
+ step_percent: int,
214
+ stages: list[tuple[str, float]],
215
+ callback: Callable[[int, str | None], None] | None = None,
216
+ ):
217
  self.enabled = bool(enabled) and bool(stages)
218
  self.step_percent = max(1, min(100, int(step_percent)))
219
  self._next_threshold = self.step_percent
220
  self._last_reported = 0
221
  self._current_stage = ""
222
+ self._callback = callback
223
 
224
  total_weight = sum(max(0.0, float(weight)) for _, weight in stages)
225
  if total_weight <= 0:
 
259
  self._emit(pct, detail=detail)
260
 
261
  def _emit(self, pct: int, detail: str | None = None) -> None:
262
+ if self._callback is not None:
263
+ self._callback(pct, detail or self._current_stage or None)
264
  if pct < self._next_threshold:
265
  return
266
  self._last_reported = pct
 
653
  return clip_paths
654
 
655
 
656
+ def run_pipeline(
657
+ input_video: str,
658
+ output_dir: str,
659
+ config_path: str | None = None,
660
+ progress_callback: Callable[[int, str | None], None] | None = None,
661
+ ) -> Dict:
662
  cfg = load_config(config_path)
663
  execution_plan = build_execution_plan(cfg)
664
  execution_cfg = cfg.get("execution", {})
 
695
  ("exports_core", 12.0),
696
  ("track_clips", 10.0 if export_track_clips_enabled else 0.0),
697
  ],
698
+ callback=progress_callback,
699
  )
700
 
701
  progress.start_stage("background")