Skip to main content

🍺 brewbar

A progress bar for Python — with beer. Drop-in compatible with the tqdm API, with extras tqdm doesn't have. Beer-themed by default; turn it off with brew=False if you need plain blocks.

Python License


The look

Working: 100% |🍺🍺🍺🍺🍺🍺🍺🍺🍺🍺🍺🍺🍺🍺🍺🍺🍺🍺🍺🍺🍺| 50/50 [00:00<00:00, 839.06it/s] cheers 🍻
Half:     50% |🍺🍺🍺🍺🍺🍺🍺🍺🍺🍺··········| 50/100 [00:00<00:00, 18.9it/s] fermenting

The bar walks through brew stages as it fills: mashing → boiling → fermenting → conditioning → cheers 🍻. Want clean Unicode blocks instead? bar(..., brew=False).


Why brewbar?

If you've used tqdm, brewbar will feel immediately familiar — same kwargs, same methods, same iterator protocol. The difference is what brewbar adds:

Feature tqdm brewbar
Iterator-based bars ✅ ✅
Manual update() mode ✅ ✅
Nested / multi bars ✅ ✅
Postfix / descriptions ✅ ✅
Dynamic miniters auto-tune ✅ ✅
pandas integration ✅ ✅
Predictive ETA (regression-based) ❌ ✅
ETA confidence intervals ❌ ✅
Memory monitoring built-in ❌ ✅
CPU monitoring built-in ❌ ✅
Rate trend sparkline ❌ ✅
Pause / resume timing ❌ ✅
Auto-color (green/yellow/red) ❌ ✅
Time budget tracking ❌ ✅
Hooks (on_update / on_complete / on_interval) ❌ ✅
Metric tracking (min/max/avg) ❌ ✅
Logging integration partial ✅
Multi-bar group manager ❌ ✅

Zero hard dependencies. Optional extras: psutil (memory/CPU), pandas.


Install

pip install brewbar              # core only
pip install brewbar[monitoring]  # + memory/CPU
pip install brewbar[pandas]      # + pandas .progress_apply
pip install brewbar[all]         # everything

Drop-in tqdm replacement

# from tqdm import tqdm, trange
from brewbar import BrewBar as tqdm, trange

for x in tqdm(range(100), desc="Training"):
    ...

for i in trange(100):
    ...

Or use brewbar's native names:

from brewbar import bar, trange, BrewBar

for x in bar(range(100), desc="Working"):
    ...

Basic usage

from brewbar import bar
import time

for _ in bar(range(100), desc="Processing"):
    time.sleep(0.05)
Processing:  47% |██████████████████▍                    | 47/100 [00:02<00:02, 18.9it/s]

Manual mode

from brewbar import BrewBar

with BrewBar(total=1024, unit="B", unit_scale=True, desc="Download") as pbar:
    for chunk in download():
        pbar.update(len(chunk))

Description + postfix (training loops)

pbar = bar(range(epochs), desc="Train")
for epoch in pbar:
    loss = train_one_epoch()
    pbar.set_postfix(loss=loss, lr=0.001, acc=0.95)

Features tqdm doesn't have

1. Predictive ETA with confidence

Standard progress bars show ETA based on average rate. brewbar uses linear regression over recent samples, and can show a confidence window:

bar(range(1000), eta_confidence=True)
Working:  42% |████████████▌                | 420/1000 [00:21<00:30±00:05, 19.8it/s]

The ±00:05 tells you how confident the estimate is. Wider window = less stable rate.

2. Memory / CPU monitoring

Requires pip install brewbar[monitoring].

bar(range(1000), show_memory=True, show_cpu=True)
Working:  42% |████████████▌      | 420/1000 [00:21<00:30, 19.8it/s] mem=1.24GiB cpu=87%

3. Rate trend sparkline

See whether your throughput is climbing or collapsing at a glance:

bar(range(1000), show_sparkline=True)
 42% |████████████▌      | 420/1000 [00:21<00:30, 19.8it/s] ▁▂▃▅▆▇█▇

4. Auto-color

Color the bar by pace, no manual logic:

bar(range(1000), auto_color=True)
# green when rate is steady/improving
# yellow when it drops
# red when it tanks

Combine with a time budget:

bar(range(1000), auto_color=True, eta_budget=60)
# green if projected completion < 60s, yellow near limit, red if over

5. Pause / resume timing

I/O waits or user interaction shouldn't count against your throughput. Pause the timer:

pbar = bar(range(100))
for i in pbar:
    process(i)
    with pbar.paused():
        input("Press enter to continue...")

Time inside paused() is excluded from elapsed/rate/ETA.

6. Hooks

def log_progress(b):
    print(f"At {b.n}/{b.total}, rate={b._avg_rate:.1f}/s")

bar(range(1000),
    on_update=lambda b: ...,                    # every render
    on_complete=lambda b: ...,                  # when done
    on_interval=(5.0, log_progress))            # every 5 seconds

7. Metric tracking

Track stats over the lifetime of the bar:

pbar = bar(range(epochs), track_metrics=["loss", "acc"])
for epoch in pbar:
    pbar.set_postfix(loss=loss(), acc=acc())

print(pbar.metric_summary())
# {'loss': {'min': 0.12, 'max': 2.30, 'avg': 0.87, 'last': 0.12, 'count': 100},
#  'acc':  {'min': 0.41, 'max': 0.96, 'avg': 0.82, 'last': 0.96, 'count': 100}}

8. Multi-bar groups

from brewbar import BarGroup

with BarGroup() as group:
    download = group.add(total=100, desc="Download")
    process  = group.add(total=100, desc="Process")
    upload   = group.add(total=100, desc="Upload")

    for i in range(100):
        download.update(); process.update(); upload.update()

9. Logging integration

Route log records through brewbar so they don't shred your bars:

import logging
from brewbar import bar, redirect_logging

redirect_logging(level=logging.INFO)
log = logging.getLogger(__name__)

for i in bar(range(100), desc="Work"):
    if i % 10 == 0:
        log.info(f"checkpoint {i}")   # appears above the bar cleanly

10. write() without breaking bars

from brewbar import bar, write

pbar = bar(range(100))
for i in pbar:
    if some_condition:
        write(f"  >> noteworthy event at {i}")   # or pbar.write(...)

Full API reference

BrewBar(iterable=None, *, ...)

All tqdm-compatible kwargs:

desc, total, leave, file, ncols, mininterval, maxinterval, miniters, ascii, disable, unit, unit_scale, unit_divisor, dynamic_ncols, smoothing, bar_format, initial, position, postfix, delay, colour / color

brewbar extras:

brew (default True — 🍺 fill glyphs and brew stage labels), show_stage, auto_color, show_memory, show_cpu, show_sparkline, sparkline_width, eta_confidence, eta_budget, on_update, on_complete, on_interval, track_metrics

Methods

.update(n=1), .refresh(), .reset(total=None), .clear(), .close(), .set_description(desc), .set_description_str(desc), .set_postfix(...), .set_postfix_str(s), .display(), .pause(), .resume(), .paused(), .metric_summary(), .write(msg)

Class methods

BrewBar.get_lock(), BrewBar.set_lock(lock), BrewBar.write(msg), BrewBar.pandas(**kw)

Module functions

bar(...), trange(...), track(...), write(...), redirect_logging(...)

bar_format fields

{n} {n_fmt} {total} {total_fmt} {percentage} {rate} {rate_fmt} {elapsed} {elapsed_fmt} {remaining} {remaining_fmt} {remaining_conf_fmt} {desc} {postfix} {unit} {bar} {memory} {cpu} {sparkline}

Example:

bar(range(100),
    bar_format="{desc} {percentage:3.0f}% [{bar}] {n_fmt}/{total_fmt} • {rate_fmt} • ETA {remaining_fmt}",
    ncols=20)

Pandas

from brewbar import BrewBar
import pandas as pd

BrewBar.pandas(desc="Computing")
df["squared"] = df["x"].progress_apply(lambda x: x * x)

Compatibility

  • Python 3.8 — 3.13
  • Linux, macOS, Windows (Windows Terminal recommended)
  • TTY-aware: silently disables in CI, pipes, and redirected output (override with disable=False)
  • NO_COLOR and FORCE_COLOR env vars honored

License

MIT

Metadata

Release files for brewbar 2.0.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for brewbar 2.0.1
File Size Uploaded Provenance
brewbar-2.0.1.tar.gz 838.2 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for brewbar 2.0.1
File Interpreter ABI Platform
brewbar-2.0.1-py3-none-any.whl Python 3 none any Details

Total release size: 855.8 kB

Release files / brewbar-2.0.1.tar.gz

Download URL brewbar-2.0.1.tar.gz
Size 838.2 kB
Tags Source
SHA-256 checksum
How to use checksums
71a01aed8797ecfd39e15df21fbe1f28c4ff2698e67eb9f607fced7b3a739e37
BLAKE2b-256 checksum
How to use checksums
474995b1b5ab9c17d0e5faa871d2531a6d1a14de0b6104678b206841c0a93e8e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.4

Release files / brewbar-2.0.1-py3-none-any.whl

Download URL brewbar-2.0.1-py3-none-any.whl
Size 17.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
9260a3f81fcb3e221b48b9f2afe13739f86456f9a53853396ad432e12fade9f3
BLAKE2b-256 checksum
How to use checksums
4a944524c4d21e2ec5e2d36d085bd6ae5f96d842fabfeba35eeb9f54bc068937
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.4

Security for brewbar 2.0.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page