CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-proglog

Log and progress bar manager for console, notebooks, web applications with unified APIs and nested progress tracking.

Pending
Overview
Eval results
Files

progress-bars.mddocs/

Progress Bar Management

Advanced progress bar functionality that extends basic logging with support for multiple named progress bars, selective display control, and automatic tracking during iteration. Includes both generic bar management (ProgressBarLogger) and concrete tqdm-powered implementation (TqdmProgressBarLogger) for visual display.

Capabilities

Generic Progress Bar Logger

Foundation class for managing multiple named progress bars with filtering and control capabilities.

class ProgressBarLogger(ProgressLogger):
    def __init__(self, init_state=None, bars=None, ignored_bars=None, 
                 logged_bars="all", min_time_interval=0, ignore_bars_under=0):
        """
        Initialize progress bar logger with bar configuration.
        
        Parameters:
        - init_state (dict, optional): Initial state dictionary
        - bars (None, list, tuple, or dict, optional): Bar configuration
          * None: Initialize with no bars
          * list/tuple: Bar names (e.g., ['main', 'sub']) with default settings
          * dict: Complete bar specifications with titles, indices, totals
        - ignored_bars (None, list, or "all_others", optional): Bars to ignore
          * None: All bars are processed
          * list: Specific bar names to ignore
          * "all_others": Ignore bars not already in self.bars
        - logged_bars ("all" or list, optional): Bars to include in logs
        - min_time_interval (float): Minimum seconds between bar updates
        - ignore_bars_under (int): Ignore bars with fewer than N items
        """

Usage Example:

from proglog import ProgressBarLogger

# Basic bar logger
logger = ProgressBarLogger()

# Pre-configured bars
logger = ProgressBarLogger(bars=["main", "subtask"])

# Detailed bar configuration
bars_config = {
    "main": {"title": "Main Task", "index": 0, "total": 100},
    "sub": {"title": "Subtask", "index": -1, "total": None}
}
logger = ProgressBarLogger(bars=bars_config)

# Selective bar display
logger = ProgressBarLogger(
    ignored_bars=["debug"],  # Don't show debug bars
    logged_bars=["main"],    # Only log main bar
    min_time_interval=0.1    # Update at most every 100ms
)

Bar Iteration

Automatically track progress while iterating through data with bar updates.

def iter_bar(self, bar_prefix="", **kw):
    """
    Iterate through data while updating a progress bar.
    
    Parameters:
    - bar_prefix (str): Prefix to add to bar name
    - **kw: Single key-value pair where key is bar name and value is iterable
    - bar_message (optional): Function to generate message from current item
    
    Returns:
    Iterator that yields items while updating progress bar
    """

Usage Example:

logger = ProgressBarLogger()

# Basic bar iteration
for item in logger.iter_bar(processing=range(100)):
    # Bar "processing" automatically updates from 0 to 99
    process_item(item)

# Nested bars with prefixes
for i in logger.iter_bar(main=range(10)):
    for j in logger.iter_bar("sub_", task=["a", "b", "c"]):
        # Creates bars "main" and "sub_task"
        do_work(i, j)

# Dynamic messages
def message_func(item):
    return f"Processing {item}"

for file in logger.iter_bar(files=file_list, bar_message=message_func):
    process_file(file)

Bar State Management

Direct control over bar attributes and behavior.

@property
def bars(self):
    """Access the bars state dictionary."""
    
def bar_is_ignored(self, bar):
    """
    Check if a bar should be ignored.
    
    Parameters:
    - bar (str): Bar name
    
    Returns:
    bool: True if bar should be ignored
    """

def bar_is_logged(self, bar):
    """
    Check if a bar should be logged.
    
    Parameters:
    - bar (str): Bar name
    
    Returns:
    bool: True if bar should be logged
    """

def bars_callback(self, bar, attr, value, old_value=None):
    """
    Custom callback for bar updates.
    
    Override in subclasses for custom bar update behavior.
    
    Parameters:
    - bar (str): Bar name
    - attr (str): Attribute being updated ("index", "total", "message")
    - value: New value
    - old_value: Previous value
    """

Usage Example:

# Manual bar updates using __call__
logger = ProgressBarLogger()

# Set bar total
logger(main__total=100)

# Update bar progress
for i in range(100):
    logger(main__index=i, main__message=f"Step {i}")
    do_work()

# Access bar state
print(logger.bars)  # Shows all bar configurations
print(logger.bar_is_ignored("main"))  # False

Tqdm Progress Bar Logger

Concrete implementation using tqdm library for visual progress bar display in console and Jupyter notebooks.

class TqdmProgressBarLogger(ProgressBarLogger):
    def __init__(self, init_state=None, bars=None, leave_bars=False,
                 ignored_bars=None, logged_bars="all", notebook="default",
                 print_messages=True, min_time_interval=0, ignore_bars_under=0):
        """
        Initialize tqdm-powered progress bar logger.
        
        Parameters:
        - init_state (dict, optional): Initial state dictionary
        - bars: Bar configuration (same as ProgressBarLogger)
        - leave_bars (bool): Whether to leave bars displayed after completion
        - ignored_bars: Bars to ignore (same as ProgressBarLogger)  
        - logged_bars: Bars to log (same as ProgressBarLogger)
        - notebook ("default", True, or False): Notebook display mode
          * "default": Use global notebook setting
          * True: Force notebook-style HTML bars
          * False: Use console-style bars
        - print_messages (bool): Whether to print logger messages
        - min_time_interval (float): Minimum seconds between updates
        - ignore_bars_under (int): Ignore iterables with fewer items
        """

Usage Example:

from proglog import TqdmProgressBarLogger
import time

# Console progress bars
logger = TqdmProgressBarLogger()

# Jupyter notebook optimized bars
logger = TqdmProgressBarLogger(notebook=True, leave_bars=True)

# Customized behavior
logger = TqdmProgressBarLogger(
    ignored_bars=["debug"],     # Don't show debug bars
    print_messages=False,       # Suppress message printing
    min_time_interval=0.05,     # Update every 50ms
    ignore_bars_under=5         # Skip bars with <5 items
)

# Usage with automatic tqdm display
for i in logger.iter_bar(main=range(100)):
    for j in logger.iter_bar(sub=range(20)):
        time.sleep(0.01)
    if i % 20 == 0:
        logger(message=f"Completed batch {i//20}")

Tqdm Bar Management

Advanced control over tqdm bar creation and lifecycle.

def new_tqdm_bar(self, bar):
    """
    Create a new tqdm progress bar.
    
    Parameters:
    - bar (str): Bar name
    """

def close_tqdm_bar(self, bar):
    """
    Close and cleanup a tqdm progress bar.
    
    Parameters:
    - bar (str): Bar name
    """

Usage Example:

logger = TqdmProgressBarLogger()

# Manual bar lifecycle management
logger.bars["custom"] = {
    "title": "Custom Task", 
    "index": 0, 
    "total": 50,
    "message": "Starting"
}
logger.new_tqdm_bar("custom")

# Update bar manually
for i in range(50):
    logger(custom__index=i, custom__message=f"Item {i}")
    time.sleep(0.1)

logger.close_tqdm_bar("custom")

Silent Progress Bar Logger

Special logger that suppresses all progress bar display while maintaining the same API.

class MuteProgressBarLogger(ProgressBarLogger):
    """
    Silent progress bar logger that ignores all bars.
    
    Provides the same API as ProgressBarLogger but suppresses
    all visual output. Useful for silent operation modes.
    """
    
    def bar_is_ignored(self, bar):
        """Always returns True - all bars are ignored."""

Usage Example:

from proglog import MuteProgressBarLogger

# Silent operation - no progress bars displayed
logger = MuteProgressBarLogger()

# Same API as other loggers, but no visual output
for item in logger.iter_bar(processing=data):
    process_item(item)  # No progress bar shown

# State tracking still works
logger(progress=50)
print(logger.state)  # {'progress': 50}

Bar Configuration Format

Bar Dictionary Structure

# Bar configuration dictionary format
bar_config = {
    "title": str,     # Display title for the bar
    "index": int,     # Current position (-1 for unstarted)
    "total": int,     # Total items (None for indeterminate)
    "message": str,   # Current status message (None for no message)
    "indent": int     # Log indentation level
}

Update Syntax

Progress bar updates use double-underscore syntax in logger calls:

# Bar attribute updates
logger(barname__total=100)      # Set total items
logger(barname__index=50)       # Update current position  
logger(barname__message="Processing...")  # Set status message

# Multiple bar updates
logger(
    main__index=10,
    sub__total=20,
    sub__index=5,
    sub__message="Subtask running"
)

Install with Tessl CLI

npx tessl i tessl/pypi-proglog

docs

basic-logging.md

index.md

progress-bars.md

workers.md

tile.json