Skip to main content

An animated and smart Progress Bar for python.

Project description

PyPI version PyPI pyversions PyPI status

alive-progress :)

An animated and smart Progress Bar for python!

Ever found yourself in a remote ssh session, doing some lengthy operations, and every now and then you feel the need to hit [enter] just to ensure you didn't lose the connection? Ever wondered where your processing is in, and when will it finish? Ever needed to pause the progress bar for a while, return to the python REPL for a manual inspection or fixing an item, and then resume the process like it never happened? I did...

I've made this thinking about all that, the Alive-Progress bar! :)

asciicast

I like to think of it as a new kind of progress bar for python, as it has among other things:

  • a cool live spinner, which makes it clear the process did not hang and your terminal/connection is healthy;
  • a visual feedback of the current speed/throughput, as the spinner runs faster or slower according to the actual processing speed;
  • an efficient multi-threaded bar, which updates itself at a fraction of the actual speed (1,000,000 iterations per second equates to roughly 60fps refresh rate) to keep CPU usage low and avoid terminal spamming;
  • an expected time of arrival (eta), that shows the remaining processing time in a friendly way, not anything like eta: 1584s, it will nicely show eta: 0:26:24 as you would expect (but anything less than a minute is indeed eta: 42s);
  • a print() hook, which allows print statements in the midst of an alive-bar context, nicely cleaning the output of any garbage, and even enriching with the current count when it occurred;
  • after your processing has finished, a nice receipt is printed with the statistics of that run, including the elapsed time and observed throughput;
  • it tracks the actual count in regard of the expected count, so it will look different if you send in more or less than expected;
  • it automatically detects if there's really an allocated tty, and if there isn't, only the final receipt is printed, so you can safely include the alive-bar in all and any code and rest assure your log file won't get 60fps garbage;
  • you can pause the alive-bar! I think that's an unprecedented feature for a progress-bar, it's incredible to orchestrate operations that request manual interaction on some items;
  • it is customizable, with a growing smorgasbord of different bar and spinner styles, as well as several factories to easily generate yours!

Get it

Just install with pip:

$ pip install alive-progress

How to use it

Use it in a with context manager like this:

from alive_progress import alive_bar
items = (1, 2, 3)                    # declare your set of items
with alive_bar(len(items)) as bar:   # declare your expected total
    for item in items:               # iterate over your items
        # process each item
        bar()                        # call after consuming one item

That's it!

In general lines, just retrieve the items, enter the alive_bar(total) context manager, and iterate/process normally, calling bar() in each iteration.

Notes

  • the items can be any iterable, and usually is some queryset;
  • the first argument of the alive_bar is the total, it could be a qs.count() for querysets, a len(items) if the iterable supports it, or anything that returns an integer;
  • the bar() call is what makes the bar go forward -- you usually call it in every iteration after consuming an item, but you can get creative! For example you could call it only when you find something you want, or call it more than once in the same iteration, depending on what you want to monitor. Just adjust the total accordingly to get a useful eta;
  • the bar() call also returns the current count if needed, and enables to pass situational messages to the bar.

So, you could even use it like:

with alive_bar(3) as bar:
    corpus = read_big_file()
    bar('file read, tokenizing')
    tokens = tokenize(corpus)
    bar('tokens ok, processing')
    process(tokens)
    bar()

Styles

Wondering what styles does it have bundled? It's showtime! ;)

asciicast

I've made these styles to test all combinations of parameters of the factories, but I think some of them ended up very very cool! Use them, or create your own.

Outputting messages

While in an alive progress bar context, you have two ways to output messages:

  • calling bar('message'), which besides incrementing the counter, also sets/overwrites a situational message within the bar line, usually to display something about the phase the processing is in, or some hint about the items being processed;
  • calling print('message'), which prints an enriched message that includes the current position of the alive bar, thus leaving behind a log and continuing the bar below it.

Both methods always clear the line appropriately to remove any garbage of previous messages on screen.

asciicast

Customization

All of the components are individually customizable, both globally and per use!

And you can mix and match them.

asciicast

Advanced

Create your own animations

Make your own spinners and bars! There's builtin support for frames, scrolling, bouncing, delayed and compound spinners! Get creative!

asciicast

The Pause mechanism

To use the pause mechanism, you must use a generator to yield the objects you want to interact with. The bar object includes another context manager to do that, just do with bar.pause(): yield obj.

Let's use an example, suppose you need to reconcile transactions. You need to iterate over thousands of them, detect somehow the faulty ones, and fix them. They could be broken or not synced or invalid or anything else, several different problems.

Typically you would have to let the process run, appending to a list each inconsistency found, and waiting, potentially a long time, until the end to be able to do anything. You could mitigate this by processing in chunks, but that has its own implications.

With the Alive-Progress bar and the Pause mechanism, you can inspect these transactions in real-time! You wait only until the next one is found! You would do something like this:

def reconcile_transactions():
    qs = Transaction.objects.filter()  # django example, or in sqlalchemy: session.query(Transaction).filter()
    with alive_bar(qs.count()) as bar:
        for transaction in qs:
            if not validate(transaction):
                with bar.pause():
                    yield transaction
            bar()

Then you could use it in ipython as:

In [12]: gen = reconcile_transactions()

In [13]: t = next(gen, None)
|███████████████▍                       | ▅▃▁ 82/200 [41%] in 4s (18.9/s, eta: 6s)

The progress bar will run as usual, but as soon as an inconsistency is found, the bar pauses itself and you get the prompt back:

In [13]: t = next(gen, None)
|█████████████████████                   | 105/200 [52%] in 5s (18.8/s, eta: 4s)

In [14]: t
Out[14]: Transaction<#123>

Debug and fix that transaction any way you want, and when you're done, continue the process with the same t = next(gen, None)... The bar returns like nothing happened!! How cool is that? :)

In [21]: t = next(gen, None)
|█████████████████████                   | ▁▃▅ 105/200 [52%] in 5s (18.8/s, eta: 4s)

Pycharm Python Console

Pycharm's python console do not report itself as "interactive", so I've included a force_tty argument to be able to use the alive-progress bar in it.

So, just start it as:

with alive_bar(1000, force_tty=1) as bar:
    for i in range(1000):
        time.sleep(.01)
        bar()

Do note that this console is heavily instrumented and has much more overhead, so the outcome is not as fluid as you would expect.

To do

  • create an unknown mode for bars (without a known total and eta)
  • implement a pausing mechanism
  • change spinner styles
  • change bar styles
  • include a global configuration system
  • create generators for scrolling, bouncing, delayed and compound spinners
  • create an exhibition of spinners and bars, to see them all in motion
  • include theme support in configuration
  • include colors in spinners and bars
  • try some adaptive algorithm for ETA, like moving average or exponential smoothing
  • any other ideas welcome!

Fun facts

  • This whole project was implemented in functional style;
  • It uses wholeheartedly Python Closures and Generators, they're very nice tools;
  • It does not declare even a single class.

Changelog highlights:

  • 1.0.1: pycharm console support, improve compatibility with python streams, support 'from alive_progress import *' in python 2.7
  • 1.0.0: first public release, already very complete and mature

License

This software is licensed under the MIT License. See the LICENSE file in the top distribution directory for the full license text.

Did you like it?

Thank you for your interest!

I've put much ❤️ and effort into this.

Hope you'll like it.

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

alive-progress-1.0.1.tar.gz (18.2 kB view details)

Uploaded Source

Built Distribution

alive_progress-1.0.1-py3-none-any.whl (16.9 kB view details)

Uploaded Python 3

File details

Details for the file alive-progress-1.0.1.tar.gz.

File metadata

  • Download URL: alive-progress-1.0.1.tar.gz
  • Upload date:
  • Size: 18.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/41.0.1 requests-toolbelt/0.9.1 tqdm/4.32.2 CPython/3.7.3

File hashes

Hashes for alive-progress-1.0.1.tar.gz
Algorithm Hash digest
SHA256 10e7942033c2fd8b1195270f5429640e93254c3c039382d7d1da261ee5a8e086
MD5 a8898ed241b8ebeb5fed2143b368fa31
BLAKE2b-256 2e2fd71875b08c0c50e892d6cdb5706996bc3b8d3ccee979721eddce89a20388

See more details on using hashes here.

File details

Details for the file alive_progress-1.0.1-py3-none-any.whl.

File metadata

  • Download URL: alive_progress-1.0.1-py3-none-any.whl
  • Upload date:
  • Size: 16.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/41.0.1 requests-toolbelt/0.9.1 tqdm/4.32.2 CPython/3.7.3

File hashes

Hashes for alive_progress-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 f828be59e67dee540700d5329304e199ef34d49a0d1ce9a9702a1aa54f33dd87
MD5 851a7b7930362932f68c76917cb0eaa8
BLAKE2b-256 aa9cc8a6d7a83dec15bd7c7956b5e4343774b09e00a67c810bf8fa1353417beb

See more details on using hashes here.

Supported by

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