hbutils.logging.progress

Lightweight progress bar utilities with optional tqdm integration.

This module provides a minimal yet practical progress bar implementation that mimics the core behavior of tqdm. When the real tqdm library is available, it is used directly; otherwise, a built-in fallback is provided.

The module contains the following main components:

  • SimpleTqdm - Lightweight progress bar with timing and ETA support

  • tqdm() - Unified progress bar factory using tqdm when installed

  • trange() - Convenience wrapper for iterating over ranges with progress

Note

The fallback implementation is intentionally lightweight and does not support all tqdm features. Unsupported keyword arguments are ignored with a warning.

Example:

>>> from hbutils.logging.progress import tqdm, trange
>>> for i in tqdm(range(3), desc="Processing"):
...     pass
Processing: 100.0% |====================| 3/3 [00:00<00:00, 3.0it/s]
>>> for i in trange(2, desc="Counting"):
...     pass
Counting: 100.0% |====================| 2/2 [00:00<00:00, 2.0it/s]

__all__

hbutils.logging.progress.__all__ = ['SimpleTqdm', 'tqdm', 'trange']

Built-in mutable sequence.

If no argument is given, the constructor creates a new empty list. The argument must be an iterable if specified.

SimpleTqdm

class hbutils.logging.progress.SimpleTqdm(iterable: Iterable[Any] | None = None, desc: str | None = None, total: int | None = None, leave: bool = True, file: TextIO | None = None, ncols: int | None = None, mininterval: float = 0.1, ascii: bool | None = None, disable: bool = False, unit: str = 'it', unit_scale: bool = False, initial: int = 0, position: int | None = None, unit_divisor: int = 1000, **kwargs: Any)[source]

A lightweight implementation of tqdm progress bar.

This class provides basic progress bar functionality similar to tqdm, with support for iteration tracking, time estimation, and customizable display.

Variables:
  • _instances (list) – Global list of all active SimpleTqdm instances

  • _lock (threading.Lock) – Thread lock for managing concurrent progress bar updates

  • _last_print_time (float) – Timestamp of the last global print operation

  • _update_interval (float) – Minimum interval between display updates

__enter__() SimpleTqdm[source]

Enter the context manager.

Returns:

Self instance

Return type:

SimpleTqdm

Example::
>>> with SimpleTqdm(range(10)) as pbar:
...     for item in pbar:
...         pass
__exit__(exc_type: type | None, exc_val: BaseException | None, exc_tb: Any | None) None[source]

Exit the context manager.

Parameters:
  • exc_type (type, optional) – Exception type if an exception occurred

  • exc_val (Exception, optional) – Exception value if an exception occurred

  • exc_tb (traceback, optional) – Exception traceback if an exception occurred

Example::
>>> with SimpleTqdm(range(10)) as pbar:
...     for item in pbar:
...         pass
__init__(iterable: Iterable[Any] | None = None, desc: str | None = None, total: int | None = None, leave: bool = True, file: TextIO | None = None, ncols: int | None = None, mininterval: float = 0.1, ascii: bool | None = None, disable: bool = False, unit: str = 'it', unit_scale: bool = False, initial: int = 0, position: int | None = None, unit_divisor: int = 1000, **kwargs: Any)[source]

Initialize a SimpleTqdm progress bar.

Parameters:
  • iterable (iterable, optional) – Iterable to decorate with a progress bar

  • desc (str, optional) – Prefix for the progress bar

  • total (int, optional) – The number of expected iterations

  • leave (bool) – If True, keep all traces of the progress bar upon termination

  • file (file-like object, optional) – Specifies where to output the progress messages

  • ncols (int, optional) – The width of the entire output message

  • mininterval (float) – Minimum progress display update interval in seconds

  • ascii (bool, optional) – If True, use ASCII characters for the progress bar

  • disable (bool) – Whether to disable the entire progress bar

  • unit (str) – String that will be used to define the unit of each iteration

  • unit_scale (bool) – If True, the number of iterations will be scaled automatically

  • initial (int) – The initial counter value

  • position (int, optional) – Specify the line offset to print this bar

  • unit_divisor (int) – Divisor for unit scaling (1000 or 1024)

  • kwargs – Additional keyword arguments (will trigger a warning if provided)

Warning

Extra keyword arguments are ignored by this lightweight implementation.

Example::
>>> with SimpleTqdm(range(5), desc="Processing") as pbar:
...     for item in pbar:
...         time.sleep(0.01)
Processing: 100.0% |====================| 5/5 [00:00<00:00, 5.0it/s]
__iter__() Iterator[Any][source]

Iterate over the wrapped iterable with progress tracking.

Returns:

Iterator yielding items from the wrapped iterable

Return type:

iterator

Raises:

TypeError – If no iterable was provided during initialization

Example::
>>> for item in SimpleTqdm(range(5)):
...     print(item)
0
1
2
3
4
clear() None[source]

Clear the current display.

This method clears the progress bar from the terminal by overwriting the current line with spaces.

Example::
>>> pbar = SimpleTqdm(range(100))
>>> pbar.clear()  # Clear the progress bar from terminal
close() None[source]

Close the progress bar and clean up resources.

This method performs a final refresh of the progress bar, adds a newline if leave is True, or clears the line if leave is False, and removes the instance from the global manager.

Example::
>>> pbar = SimpleTqdm(range(100))
>>> for item in pbar:
...     pass
>>> pbar.close()
refresh() None[source]

Force refresh of the progress bar display.

Example::
>>> pbar = SimpleTqdm(total=100)
>>> pbar.n = 50
>>> pbar.refresh()  # Force display update
set_description(desc: str | None = None, refresh: bool = True) None[source]

Set the progress bar description.

Parameters:
  • desc (str, optional) – New description text

  • refresh (bool) – Whether to refresh the display immediately

Example::
>>> pbar = SimpleTqdm(range(100))
>>> pbar.set_description("Processing files")
set_postfix(ordered_dict: dict | None = None, refresh: bool = True, **kwargs: Any) None[source]

Set postfix information (simplified implementation, not actually displayed).

This method exists for API compatibility with tqdm but does not display the postfix information in SimpleTqdm.

Parameters:
  • ordered_dict (dict, optional) – Dictionary of postfix key-value pairs

  • refresh (bool) – Whether to refresh the display immediately

  • kwargs – Additional postfix key-value pairs

Example::
>>> pbar = SimpleTqdm(range(100))
>>> pbar.set_postfix(loss=0.5, accuracy=0.95)
update(n: int = 1) None[source]

Update the progress bar by incrementing the counter.

Parameters:

n (int) – Increment to add to the internal counter

Example::
>>> pbar = SimpleTqdm(total=100)
>>> pbar.update(10)
>>> pbar.n
10
write(s: str, file: TextIO | None = None, end: str = '\n', nolock: bool = False) None[source]

Write text without disrupting the progress bar display.

This method allows writing messages to the output stream without interfering with the progress bar. It temporarily clears the progress bar, writes the message, and then refreshes the progress bar.

Parameters:
  • s (str) – String to write

  • file (file-like object, optional) – File object to write to

  • end (str) – String appended after the last value

  • nolock (bool) – If True, don’t use the global lock

Example::
>>> pbar = SimpleTqdm(range(100))
>>> pbar.write("Processing complete")

tqdm

hbutils.logging.progress.tqdm(iterable: Iterable[Any] | None = None, desc: str | None = None, total: int | None = None, leave: bool = True, file: TextIO | None = None, ncols: int | None = None, mininterval: float = 0.1, ascii: bool | None = None, disable: bool = False, unit: str = 'it', unit_scale: bool = False, initial: int = 0, position: int | None = None, unit_divisor: int = 1000, **kwargs: Any) SimpleTqdm | Any[source]

tqdm-compatible interface for creating progress bars.

This function provides a unified interface that uses the real tqdm library if available, otherwise falls back to SimpleTqdm. It maintains API compatibility with the standard tqdm library while providing a lightweight alternative when tqdm is not installed.

Parameters:
  • iterable (iterable, optional) – Iterable to decorate with a progress bar

  • desc (str, optional) – Prefix for the progress bar

  • total (int, optional) – The number of expected iterations

  • leave (bool) – If True, keep all traces of the progress bar upon termination

  • file (file-like object, optional) – Specifies where to output the progress messages

  • ncols (int, optional) – The width of the entire output message

  • mininterval (float) – Minimum progress display update interval in seconds

  • ascii (bool, optional) – If True, use ASCII characters for the progress bar

  • disable (bool) – Whether to disable the entire progress bar

  • unit (str) – String that will be used to define the unit of each iteration

  • unit_scale (bool) – If True, the number of iterations will be scaled automatically

  • initial (int) – The initial counter value

  • position (int, optional) – Specify the line offset to print this bar

  • unit_divisor (int) – Divisor for unit scaling (1000 or 1024)

  • kwargs – Additional keyword arguments passed to the underlying implementation

Returns:

Progress bar instance (either real tqdm or SimpleTqdm)

Return type:

tqdm or SimpleTqdm

Example::
>>> for i in tqdm(range(3), desc="Processing"):
...     time.sleep(0.01)
Processing: 100.0% |====================| 3/3 [00:00<00:00, 3.0it/s]

trange

hbutils.logging.progress.trange(*args: int, **kwargs: Any) SimpleTqdm | Any[source]

Shortcut for tqdm(range(*args), **kwargs).

This is a convenience function that creates a progress bar for a range iterator. It’s equivalent to calling tqdm(range(*args), **kwargs).

Parameters:
  • args (int) – Positional arguments passed to range()

  • kwargs – Keyword arguments passed to tqdm()

Returns:

Progress bar instance wrapping a range iterator

Return type:

tqdm or SimpleTqdm

Example::
>>> for i in trange(3, desc="Counting"):
...     time.sleep(0.01)
Counting: 100.0% |====================| 3/3 [00:00<00:00, 3.0it/s]