Skip to main content

Stage-aware progress monitoring for parallel Python jobs

Project description

ProgressBox

Stage-aware progress monitoring for parallel Python jobs.

Python Version License Status

Features

  • Stage-aware tracking - Monitor different stages of computation with timing analysis
  • True parallelism - Built for multiprocessing, threading, and joblib
  • Rich statistics - ETA, throughput, stage timing breakdown
  • Multiple renderers - Terminal, Jupyter notebooks, or plain string output
  • Production ready - Logging, snapshots, callbacks, error handling

Installation

pip install progressbox

For development:

git clone https://github.com/yourorg/progressbox.git
cd progressbox
pip install -e .

Quick Start

Basic Usage

from progressbox import Progress, Config

config = Config(total=100, n_workers=4)
with Progress(config) as progress:
    for i in range(100):
        progress.task_start(f"task_{i}")
        # ... do work ...
        progress.task_finish(f"task_{i}")

With Stages

Track different phases of each task:

from progressbox import Progress, Config

config = Config(total=100)
with Progress(config) as progress:
    for i in range(100):
        progress.task_start(f"task_{i}")

        progress.task_update(f"task_{i}", stage="loading")
        data = load_data(i)

        progress.task_update(f"task_{i}", stage="processing")
        result = process(data)

        progress.task_update(f"task_{i}", stage="saving")
        save(result)

        progress.task_finish(f"task_{i}")

With Callbacks

Get notified on completion:

from progressbox import Progress, Config

def on_complete(snapshot):
    print(f"Processed {snapshot['completed']} tasks")
    print(f"Total time: {snapshot['elapsed']:.1f}s")

config = Config(total=100, on_complete=on_complete)
with Progress(config) as progress:
    # ... process tasks ...

Display Example

+======================================================================+
|                       Progress Monitoring                             |
+======================================================================+
| Progress: [################............] 42/100 (42%)                |
| Elapsed: 1m 23s | ETA: 1m 52s | Rate: 0.5 tasks/s                    |
+----------------------------------------------------------------------+
| Stage Analysis                                                        |
|   loading:     0.8s avg (32%)                                        |
|   processing:  1.2s avg (48%)                                        |
|   saving:      0.5s avg (20%)                                        |
+----------------------------------------------------------------------+
| Active Workers                                                        |
|   W0: processing  [####....] 1.2s                                    |
|   W1: loading     [##......] 0.3s                                    |
|   W2: saving      [######..] 0.4s                                    |
+======================================================================+

Configuration Reference

Config(
    # Required
    total=100,                    # Total number of tasks

    # Display options
    n_workers=6,                  # Number of worker rows to display
    inner_width=68,               # Display width (60, 68, 84, 100, or "auto")
    unicode=True,                 # Use Unicode box characters
    renderer="ascii",             # "ascii", "string", "jupyter", or "rich"

    # Feature toggles
    show_stage_analysis=True,     # Show stage timing breakdown
    show_workers=True,            # Show active worker list
    max_active_rows=12,           # Max worker rows to display

    # Performance
    refresh_hz=8.0,               # Display refresh rate
    display_interval=0.1,         # Minimum time between renders

    # Metrics
    ewma_alpha=0.2,               # ETA smoothing factor
    cache_speed_factor=0.8,       # Speed adjustment for cached tasks

    # Production settings
    fail_safe=True,               # Never raise exceptions
    headless_ok=True,             # Allow headless operation
    prod_safe=False,              # Conservative mode for production

    # Callbacks
    on_snapshot=None,             # Called periodically with state
    on_complete=None,             # Called when all tasks complete
    snapshot_interval_s=10.0,     # Seconds between snapshots
    log_interval_s=30.0,          # Seconds between log messages
)

API Reference

Progress Class

from progressbox import Progress, Config

config = Config(total=100)
progress = Progress(config)

# Context manager (recommended)
with Progress(config) as p:
    p.task_start(task_id)
    p.task_update(task_id, stage="working")
    p.task_finish(task_id)

# Manual control
progress.start()           # Start rendering
progress.stop()            # Stop rendering (keeps state)
progress.close()           # Final cleanup
progress.tick()            # Force render update

Task Methods

# Start tracking a task
progress.task_start(
    task_id,              # Unique task identifier
    worker=None,          # Worker ID (auto-assigned if None)
    cached=False,         # Whether task uses cached results
    meta=None             # Optional metadata dict
)

# Update task state
progress.task_update(
    task_id,
    stage=None,           # New stage name
    progress=None,        # Progress ratio (0.0-1.0)
    sub_progress=None     # Sub-progress as (current, total)
)

# Mark task complete
progress.task_finish(task_id)

# Aliases
progress.stage_transition(task_id, stage)  # Same as task_update with stage
progress.stage_progress(task_id, ratio)    # Same as task_update with progress
progress.task_complete(task_id)            # Same as task_finish

Helper Functions

from progressbox import create_default_config

# Create config with sensible defaults
config = create_default_config(
    total=100,
    n_workers=8,
    renderer="string"
)

Renderers

ProgressBox automatically selects the best renderer for your environment:

Environment Default Renderer
Terminal (TTY) ascii - Unicode box drawing
Jupyter notebook jupyter - HTML with styling
Headless/CI string - Plain text

Force a specific renderer:

config = Config(total=100, renderer="string")

Joblib Integration

from joblib import Parallel, delayed
from progressbox.adapters import joblib_progress

def process(item):
    # Your processing function
    return result

items = list(range(100))

with joblib_progress(total=len(items)) as progress:
    results = Parallel(n_jobs=4)(
        delayed(process)(item) for item in items
    )

Thread Safety

All task methods (task_start, task_update, task_finish) are thread-safe and can be called from multiple workers concurrently.

Error Handling

By default, ProgressBox operates in fail-safe mode (fail_safe=True), catching and logging errors without interrupting your workflow. For strict error handling:

config = Config(total=100, fail_safe=False)

License

MIT License - see LICENSE file for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

progressbox-0.1.0.tar.gz (62.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

progressbox-0.1.0-py3-none-any.whl (57.9 kB view details)

Uploaded Python 3

File details

Details for the file progressbox-0.1.0.tar.gz.

File metadata

  • Download URL: progressbox-0.1.0.tar.gz
  • Upload date:
  • Size: 62.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for progressbox-0.1.0.tar.gz
Algorithm Hash digest
SHA256 cc5e1be90057a2f1769f3e6ee5f5ff092c8bb3d5123c179696ee55c465db6a64
MD5 5fcee8fbf7109e1fb51aee108deed0cc
BLAKE2b-256 2465c6f3d1e15ecb7aa9d3098e4f3404a5d5ef4babc464e730000d350e5e43af

See more details on using hashes here.

Provenance

The following attestation bundles were made for progressbox-0.1.0.tar.gz:

Publisher: publish.yml on ZaafirH/progressbox

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file progressbox-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: progressbox-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 57.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for progressbox-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 6cf695d7d11e311452f92ace404af2f75e01bd367f9efb2169156cb1c9f47fe0
MD5 4858d460887a79897933ec9bb5e8ddc5
BLAKE2b-256 b446ff09d10e0b20b1dcd9a71d740f0f2ef9258af4765b115b2d74b7e98c7e8f

See more details on using hashes here.

Provenance

The following attestation bundles were made for progressbox-0.1.0-py3-none-any.whl:

Publisher: publish.yml on ZaafirH/progressbox

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page