
Have you ever wondered where your lengthy processing was at, and when would it finish? Do you usually hit RETURN several times to make sure it didn't crash, or the SSH connection didn't freeze? Have you ever thought it'd be awesome to be able to pause some processing without hassle, return to the Python prompt to manually fix some items, then seamlessly resume it? I did...
I've started this new progress bar thinking about all that, behold the alive-progress! 😃

Introducing the newest concept in progress bars for Python! alive-progress is in a class of its own, with an array of cool features that set it apart. Here are a few highlights:
check() tool that helps you design your own animations! You can see how the generated frames and animation cycles will look like, exploded on your screen, and even see it alive before installing in alive-progress! It's the coolest tool in the world! Unleash your creativity!This README is always evolving, so do take a more comprehensive look from time to time... You might find great new details in other sections! 😊
alive-progress
bar handlerThe latest alive-progress release is finally here, and it brings some exciting improvements! 🎉
Here's a summary of the most notable changes:
Technical changes:
grapheme dependency which was no longer maintained to graphemeu, which is a maintained fork of the original one.py.typed in the distribution to satisfy mypy and other type checking tools.New in 3.2 series
After about a year of reassuring stability, the new alive-progress has finally landed!
The main features and improvements are:
bar() with 0 and even -N to make it go backwards! Useful when you couldn't make any progress in an iteration or had to roll back something!And more!
enrich_offset to use for printed or logged messages, allowing you to start with on 1: or continue where you left from previous computations!New in 3.1 series
A very cool update here! In addition to polishing things up and improving terminal support, now alive-progress supports resuming computations!
When processing huge datasets or things that take a long time, you might either use batches or cache partial results. Then, in case it stops and is restarted, you end up skipping all those already done items very quickly, which makes the alive_bar think you're processing thousands of items per second, which in turn completely ruins the ETA... But not anymore! Just tell bar() that you've skipped items... 👏
You can use it in two ways:
1. If you do know where you've stopped:
with alive_bar(120000) as bar:
bar(60000, skipped=True)
for i in range(60000, 120000):
# process item
bar()
Yep, just call bar(N, skipped=True) once, with the number of items.
2. If you do not know or the items are scattered:
with alive_bar(120000) as bar:
for i in range(120000):
if done(i):
bar(skipped=True)
continue
# process item
bar()
Yep, it's as simple as that! Just call bar(skipped=True) when an item is already done, or bar() as usual otherwise. You could also share a single bar(skipped=?) call at the end, with a bool saying whether you did skip that item or not. Cool, huh?
Also in this version:
max_cols config setting, the number of columns to use if not possible to fetch it, like in jupyter and other platforms which doesn't support sizeNew in 3.0 series
Yep, I could finally get this version out! These are the new goodies:
B, bytes, or even °C!sys.stderr and other files instead of sys.stdout!Highly anticipated fixes:
TypeError: unhashable type: 'types.SimpleNamespace'.RotatingFileHandlers! Yep, seek support is here.And last but not least, a more polished layout for you to enjoy your progress!

New in 2.4 series
Now, alive_bar supports Dual Line text mode!
If you ever wanted to include longer situational messages within the bar, you probably felt squeezed into one line. You had to shrink the beautifully animated bar or, even worse, remove widgets (!) to be able to see what you needed...
Not anymore!! You can now make the bar Dual Line, and put text below it!
Yes, there's a message below the whole bar, and any other print/logging messages scroll above it!
letters = [chr(ord('A') + x) for x in range(26)]
with alive_bar(26, dual_line=True, title='Alphabet') as bar:
for c in letters:
bar.text = f'-> Teaching the letter: {c}, please wait...'
if c in 'HKWZ':
print(f'fail "{c}", retry later')
time.sleep(0.3)
bar()
Output:
on 7: fail "H", retry later
on 10: fail "K", retry later
Alphabet |███████████████████████████▊ | ▃▅▇ 18/26 [69%] in 6s (3.2/s, eta: 3s)
-> Teaching the letter: S, please wait...
There's also a new finalize function parameter in alive_it which enables you to set the title and/or text of the final receipt, and improved logging support which detects customized loggers.
New in 2.3 series
This is all about customization; the core widgets can now be changed:
monitor, elapsed, and stats widgets to make them look anyway you want!It's incredible that these strings support all Python format features, so you can e.g.,
{percent:.1%}😉.
They can be further customized when on the final receipt!
monitor_end, elapsed_end, and stats_end, with dynamic formats inherited from the standard ones!If you've hidden some widgets before, just so they wouldn't appear on the receipt, now you can see them in all their running glory, and hide just the receipt ones! Or the other way around 😜
Another addition, now alive-progress beautifully renders its cool final receipt whenever it is stopped, even if you CTRL+C it prematurely! I don't know why I haven't thought about that before...
Download |██████████████████⚠︎ | (!) 45/100 [45%] in 4.8s (9.43/s)
And finally, you can choose to disable CTRL+C at all! The default is the safer ctrl_c=True, which does make CTRL-C work as usual.
Disable it `ctrl_c=F
$ claude mcp add alive-progress \
-- python -m otcore.mcp_server <graph>