Put live values in the prefix or suffix

A fixed string works for a label that never changes, but a prefix that names the file currently being processed, or a suffix that shows the running count, needs to be re-evaluated on every redraw.

Live file and block labels
"""Show the current file and processed blocks in prefix/suffix templates.

Each file takes twenty small steps. Both templates read the same live
bar data on every redraw, including the filename supplied to update().
"""

import time

import progressbar

FILES: list[str] = [
    'users.csv',
    'sales.csv',
    'stock.csv',
    'costs.csv',
    'audit.csv',
]
BLOCKS_PER_FILE: int = 20


def main() -> None:
    completed: int = 0
    bar: progressbar.ProgressBar
    file_number: int
    filename: str
    _block: int
    with progressbar.ProgressBar(
        max_value=len(FILES) * BLOCKS_PER_FILE,
        prefix='{variables.filename} {variables.file_number}/5 ',
        suffix=' {value:3}/{max_value} blocks',
        variables={'filename': FILES[0], 'file_number': 1},
        widgets=[progressbar.Percentage(), ' ', progressbar.Bar()],
    ) as bar:
        for file_number, filename in enumerate(FILES, start=1):
            for _block in range(BLOCKS_PER_FILE):
                time.sleep(0.02)
                completed += 1
                bar.update(
                    completed, filename=filename, file_number=file_number
                )


if __name__ == '__main__':
    main()

The prefix names the current CSV file and its position in the batch. The suffix counts processed blocks across all five files. Each file has twenty blocks, so the bar advances a hundred times while the filename changes only five times. The filename column and block count keep a fixed width as their values change.

Both prefix= and suffix= accept a str.format() template evaluated against the bar’s data on every redraw, not just a plain string: use {value}, {max_value}, or any other key the built-in widgets read. A custom entry works the same way as in Show a custom value next to the bar – seed it through variables= (or let it default), then reach it in the template as {variables.<name>}, and update it by name through bar.update(step, <name>=...).