Common Patterns

Enable / Disable

A program may want to disable progress bars based on a configuration setting as well as if output redirection occurs.

import sys
import enlighten

# Example configuration object
config = {'stream': sys.stdout,
          'useCounter': False}

enableCounter = config['useCounter'] and stream.isatty()
manager = enlighten.Manager(stream=config['stream'], enabled=enableCounter)

The get_manager() function slightly simplifies this

import enlighten

# Example configuration object
config = {'stream': None,  # Defaults to sys.__stdout__
          'useCounter': False}

manager = enlighten.get_manager(stream=config['stream'], enabled=config['useCounter'])

Context Managers

Both Counter and Manager can be used as context managers.

import enlighten

SPLINES = 100

with enlighten.Manager() as manager:
    with manager.counter(total=SPLINES, desc='Reticulating:', unit='splines') as retic:
        for num in range(1, SPLINES + 1):
            time.sleep(.1)
            retic.update()

Automatic Updating

Both Counter and SubCounter instances can be called as functions on one or more iterators. A generator is returned which yields each element of the iterables and then updates the count by 1.

Note

When a Counter instance is called as a function, type checking is lazy and won't validate an iterable was passed until iteration begins.

import time
import enlighten

flock1 = ['Harry', 'Sally', 'Randy', 'Mandy', 'Danny', 'Joe']
flock2 = ['Punchy', 'Kicky', 'Spotty', 'Touchy', 'Brenda']
total = len(flock1) + len(flock2)

manager = enlighten.Manager()
pbar = manager.counter(total=total, desc='Counting Sheep', unit='sheep')

for sheep in pbar(flock1, flock2):
    time.sleep(0.2)
    print('%s: Baaa' % sheep)

User-defined fields

Both Counter and StatusBar accept user defined fields as keyword arguments at initialization and during an update. These fields are persistent and only need to be specified when they change.

In the following example, source is a user-defined field that is periodically updated.

import enlighten
import random
import time

bar_format = u'{desc}{desc_pad}{source} {percentage:3.0f}%|{bar}| ' + \
             u'{count:{len_total}d}/{total:d} ' + \
             u'[{elapsed}<{eta}, {rate:.2f}{unit_pad}{unit}/s]'
manager = enlighten.get_manager(bar_format=bar_format)

bar = manager.counter(total=100, desc='Loading', unit='files', source='server.a')
for num in range(100):
    time.sleep(0.1)  # Simulate work
    if not num % 5:
        bar.update(source=random.choice(['server.a', 'server.b', 'server.c']))
    else:
        bar.update()

For more information, see the Counter Format and StatusBar Format sections.

Human-readable numeric prefixes

Enlighten supports automatic SI (metric) and IEC (binary) prefixes using the Prefixed library.

All rate and interval formatting fields are of the type prefixed.Float. total and all count fields default to int. If total or or count are set to a float, or a float is provided to update(), these fields will be prefixed.Float instead.

import time
import random
import enlighten

size = random.uniform(1.0, 10.0) * 2 ** 20  # 1-10 MiB (float)
chunk_size = 64 * 1024  # 64 KiB

bar_format = '{desc}{desc_pad}{percentage:3.0f}%|{bar}| ' \
             '{count:!.2j}{unit} / {total:!.2j}{unit} ' \
             '[{elapsed}<{eta}, {rate:!.2j}{unit}/s]'

manager = enlighten.get_manager()
pbar = manager.counter(total=size, desc='Downloading', unit='B', bar_format=bar_format)

bytes_left = size
while bytes_left:
    time.sleep(random.uniform(0.05, 0.15))
    next_chunk = min(chunk_size, bytes_left)
    pbar.update(next_chunk)
    bytes_left -= next_chunk
import enlighten

counter_format = 'Trying to get to sleep: {count:.2h} sheep'

manager = enlighten.get_manager()
counter = manager.counter(counter_format=counter_format)
counter.count = 0.0
for num in range(10000000):
    counter.update()

For more information, see the Counter Format and the Prefixed documentation.

Manually Printing

By default, if the manager's stream is connected to a TTY, bars and counters are automatically printed and updated. There may, however be cases where manual output is desired in addition to or instead of the automatic output. For example, to send to other streams or print to a file.

The output for an individual bar can be retrieved from the format() method. This supports optional arguments to specify width and elapsed time.

import enlighten

manager = enlighten.get_manager(enabled=False)
pbar = manager.counter(desc='Progress', total=10)

pbar.update()
print(pbar.format(width=100))

As a shortcut, the counter object will call the format() method with the default arguments when coerced to a string.

import enlighten

manager = enlighten.get_manager(enabled=False)
pbar = manager.counter(desc='Progress', total=10)

pbar.update()
print(pbar)

While Enlighten's default output provides more advanced capability, A basic refreshing progress bar can be created like so.

import enlighten
import time

manager = enlighten.get_manager(enabled=False)
pbar = manager.counter(desc='Progress', total=10)

print()

for num in range(10):
    time.sleep(0.2)
    pbar.update()
    print(f'\r{pbar}', end='', flush=True)

print()