🍺 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.
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_COLORandFORCE_COLORenv 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)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| brewbar-2.0.1.tar.gz | 838.2 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| 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.