From c6e84598801c6071800a9a7e553e30933029e4fd Mon Sep 17 00:00:00 2001 From: Hoyt Koepke Date: Mon, 21 Jul 2025 16:37:31 -0700 Subject: [PATCH 1/3] Update to use simple bar for notebook reporting. --- .../utils/_xet_progress_reporting.py | 47 ++++++++++++++----- src/huggingface_hub/utils/tqdm.py | 7 +++ 2 files changed, 43 insertions(+), 11 deletions(-) diff --git a/src/huggingface_hub/utils/_xet_progress_reporting.py b/src/huggingface_hub/utils/_xet_progress_reporting.py index 8249066311..52801b2831 100644 --- a/src/huggingface_hub/utils/_xet_progress_reporting.py +++ b/src/huggingface_hub/utils/_xet_progress_reporting.py @@ -5,18 +5,30 @@ from .tqdm import tqdm - class XetProgressReporter: - def __init__(self, n_lines: int = 10, description_width: int = 40): + """ + Reports on progress for Xet uploads. + + If per_file_progress is True, then per-file progress is shown in a scrolling list. Otherwise, + only the summary bars showing file processing progress and data upload are shown. By default, + the summary version is shown in notebooks and the detailed file progress is shown in consoles. + """ + + def __init__(self, n_lines: int = 10, description_width: int = 30, per_file_progress = None): self.n_lines = n_lines self.description_width = description_width + if per_file_progress is None: + self.per_file_progress = not tqdm.in_notebook() + else: + self.per_file_progress = per_file_progress + self.tqdm_settings = { "unit": "B", "unit_scale": True, "leave": True, "unit_divisor": 1000, - "nrows": n_lines + 3, + "nrows": n_lines + 3 if self.per_file_progress else 3, "miniters": 1, "bar_format": "{l_bar}{bar}| {n_fmt:>5}B / {total_fmt:>5}B{postfix:>12}", } @@ -40,8 +52,13 @@ def __init__(self, n_lines: int = 10, description_width: int = 40): def format_desc(self, name: str, indent: bool) -> str: """ if name is longer than width characters, prints ... at the start and then the last width-3 characters of the name, otherwise - the whole name right justified into 20 characters. Also adds some padding. + the whole name right justified into description_width characters. Also adds some padding. """ + + if not self.per_file_progress: + # Here we just use the defaults. + return name + padding = " " if indent else "" width = self.description_width - len(padding) @@ -51,6 +68,7 @@ def format_desc(self, name: str, indent: bool) -> str: return f"{padding}{name.ljust(width)}" def update_progress(self, total_update: PyTotalProgressUpdate, item_updates: List[PyItemProgressUpdate]): + # Update all the per-item values. for item in item_updates: item_name = item.item_name @@ -74,6 +92,10 @@ def update_progress(self, total_update: PyTotalProgressUpdate, item_updates: Lis self.completed_items.add(name) new_completed.append(name) + # If we're only showing summary information, then don't update the individual bars + if not self.per_file_progress: + continue + # If we've run out of bars to use, then collapse the last ones together. if bar_idx >= len(self.current_bars): bar = self.current_bars[-1] @@ -111,10 +133,11 @@ def update_progress(self, total_update: PyTotalProgressUpdate, item_updates: Lis del self.item_state[name] - # Now manually refresh each of the bars - for bar in self.current_bars: - if bar: - bar.refresh() + if self.per_file_progress: + # Now manually refresh each of the bars + for bar in self.current_bars: + if bar: + bar.refresh() # Update overall bars def postfix(speed): @@ -136,6 +159,8 @@ def postfix(speed): def close(self, _success): self.data_processing_bar.close() self.upload_bar.close() - for bar in self.current_bars: - if bar: - bar.close() + + if self.per_file_progress: + for bar in self.current_bars: + if bar: + bar.close() diff --git a/src/huggingface_hub/utils/tqdm.py b/src/huggingface_hub/utils/tqdm.py index 4c1fcef4be..0e9f8df9ce 100644 --- a/src/huggingface_hub/utils/tqdm.py +++ b/src/huggingface_hub/utils/tqdm.py @@ -89,6 +89,7 @@ from typing import ContextManager, Dict, Iterator, Optional, Union from tqdm.auto import tqdm as old_tqdm +from tqdm.notebook import tqdm as _notebook_tqdm from ..constants import HF_HUB_DISABLE_PROGRESS_BARS @@ -232,6 +233,12 @@ def __delattr__(self, attr: str) -> None: if attr != "_lock": raise + @classmethod + def in_notebook(cls) -> bool: + """Returns true if running in a notebook environment and false if running in a console.""" + + return _notebook_tqdm in cls.mro() + @contextmanager def tqdm_stream_file(path: Union[Path, str]) -> Iterator[io.BufferedReader]: From f0215d7f2232caa2655e4fd08b4d6c326f2724d8 Mon Sep 17 00:00:00 2001 From: Hoyt Koepke Date: Mon, 21 Jul 2025 16:49:32 -0700 Subject: [PATCH 2/3] Update to also deal with gui's, etc. --- src/huggingface_hub/utils/_xet_progress_reporting.py | 4 ++-- src/huggingface_hub/utils/tqdm.py | 10 ++++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/huggingface_hub/utils/_xet_progress_reporting.py b/src/huggingface_hub/utils/_xet_progress_reporting.py index 52801b2831..bc5ab12c1b 100644 --- a/src/huggingface_hub/utils/_xet_progress_reporting.py +++ b/src/huggingface_hub/utils/_xet_progress_reporting.py @@ -11,7 +11,7 @@ class XetProgressReporter: If per_file_progress is True, then per-file progress is shown in a scrolling list. Otherwise, only the summary bars showing file processing progress and data upload are shown. By default, - the summary version is shown in notebooks and the detailed file progress is shown in consoles. + the summary version is shown in notebooks and guis and the detailed file progress is shown in consoles. """ def __init__(self, n_lines: int = 10, description_width: int = 30, per_file_progress = None): @@ -19,7 +19,7 @@ def __init__(self, n_lines: int = 10, description_width: int = 30, per_file_prog self.description_width = description_width if per_file_progress is None: - self.per_file_progress = not tqdm.in_notebook() + self.per_file_progress = tqdm.in_console() else: self.per_file_progress = per_file_progress diff --git a/src/huggingface_hub/utils/tqdm.py b/src/huggingface_hub/utils/tqdm.py index 0e9f8df9ce..a3e0e4ca9f 100644 --- a/src/huggingface_hub/utils/tqdm.py +++ b/src/huggingface_hub/utils/tqdm.py @@ -89,7 +89,7 @@ from typing import ContextManager, Dict, Iterator, Optional, Union from tqdm.auto import tqdm as old_tqdm -from tqdm.notebook import tqdm as _notebook_tqdm +from tqdm.std import tqdm as std_tqdm from ..constants import HF_HUB_DISABLE_PROGRESS_BARS @@ -234,10 +234,12 @@ def __delattr__(self, attr: str) -> None: raise @classmethod - def in_notebook(cls) -> bool: - """Returns true if running in a notebook environment and false if running in a console.""" + def in_console(cls) -> bool: + """Returns true if running in a standard console environment and false if running in a notebook or gui.""" - return _notebook_tqdm in cls.mro() + # Returns true if the current display method is the one in the standard tqdm class, or false if it's been + # overwritten by the gui, notebook, keras, etc. subclassing it. + return cls.display is std_tqdm.display @contextmanager From 7334f06e7f0f802c73ce4d6fbe0e1c8a1f4840b9 Mon Sep 17 00:00:00 2001 From: Hoyt Koepke Date: Mon, 21 Jul 2025 17:03:34 -0700 Subject: [PATCH 3/3] Updated style. --- .../utils/_xet_progress_reporting.py | 16 ++++++++-------- src/huggingface_hub/utils/tqdm.py | 6 +++--- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/huggingface_hub/utils/_xet_progress_reporting.py b/src/huggingface_hub/utils/_xet_progress_reporting.py index bc5ab12c1b..6f1b28d4c0 100644 --- a/src/huggingface_hub/utils/_xet_progress_reporting.py +++ b/src/huggingface_hub/utils/_xet_progress_reporting.py @@ -5,22 +5,23 @@ from .tqdm import tqdm + class XetProgressReporter: """ Reports on progress for Xet uploads. - - If per_file_progress is True, then per-file progress is shown in a scrolling list. Otherwise, - only the summary bars showing file processing progress and data upload are shown. By default, + + If per_file_progress is True, then per-file progress is shown in a scrolling list. Otherwise, + only the summary bars showing file processing progress and data upload are shown. By default, the summary version is shown in notebooks and guis and the detailed file progress is shown in consoles. """ - def __init__(self, n_lines: int = 10, description_width: int = 30, per_file_progress = None): + def __init__(self, n_lines: int = 10, description_width: int = 30, per_file_progress=None): self.n_lines = n_lines self.description_width = description_width if per_file_progress is None: - self.per_file_progress = tqdm.in_console() - else: + self.per_file_progress = tqdm.in_console() + else: self.per_file_progress = per_file_progress self.tqdm_settings = { @@ -56,7 +57,7 @@ def format_desc(self, name: str, indent: bool) -> str: """ if not self.per_file_progress: - # Here we just use the defaults. + # Here we just use the defaults. return name padding = " " if indent else "" @@ -68,7 +69,6 @@ def format_desc(self, name: str, indent: bool) -> str: return f"{padding}{name.ljust(width)}" def update_progress(self, total_update: PyTotalProgressUpdate, item_updates: List[PyItemProgressUpdate]): - # Update all the per-item values. for item in item_updates: item_name = item.item_name diff --git a/src/huggingface_hub/utils/tqdm.py b/src/huggingface_hub/utils/tqdm.py index a3e0e4ca9f..b6326cef56 100644 --- a/src/huggingface_hub/utils/tqdm.py +++ b/src/huggingface_hub/utils/tqdm.py @@ -234,11 +234,11 @@ def __delattr__(self, attr: str) -> None: raise @classmethod - def in_console(cls) -> bool: + def in_console(cls) -> bool: """Returns true if running in a standard console environment and false if running in a notebook or gui.""" - # Returns true if the current display method is the one in the standard tqdm class, or false if it's been - # overwritten by the gui, notebook, keras, etc. subclassing it. + # Returns true if the current display method is the one in the standard tqdm class, or false if it's been + # overwritten by the gui, notebook, keras, etc. subclassing it. return cls.display is std_tqdm.display