#!/usr/bin/python
from __future__ import annotations
import contextlib
import functools
import os
import random
import sys
import time
import typing
import progressbar
examples: list[typing.Callable[[typing.Any], typing.Any]] = []
def example(fn):
"""Wrap the examples so they generate readable output"""
@functools.wraps(fn)
def wrapped(*args, **kwargs):
try:
sys.stdout.write(f'Running: {fn.__name__}\n')
fn(*args, **kwargs)
sys.stdout.write('\n')
except KeyboardInterrupt:
sys.stdout.write('\nSkipping example.\n\n')
# Sleep a bit to make killing the script easier
time.sleep(0.2)
examples.append(wrapped)
return wrapped
@example
def fast_example() -> None:
"""Updates bar really quickly to cause flickering"""
with progressbar.ProgressBar(widgets=[progressbar.Bar()]) as bar:
for i in range(100):
bar.update(int(i / 10), force=True)
@example
def shortcut_example() -> None:
for _ in progressbar.progressbar(range(10)):
time.sleep(0.1)
@example
def prefixed_shortcut_example() -> None:
for _ in progressbar.progressbar(range(10), prefix='Hi: '):
time.sleep(0.1)
@example
def parallel_bars_multibar_example() -> None:
if os.name == 'nt':
print(
'Skipping multibar example on Windows due to threading '
'incompatibilities with the example code.'
)
return
BARS = 5
N = 50
def do_something(bar):
for _ in bar(range(N)):
# Sleep up to 0.1 seconds
time.sleep(random.random() * 0.1)
with progressbar.MultiBar() as multibar:
bar_labels = []
for i in range(BARS):
# Get a progressbar
bar_label = f'Bar #{i:d}'
bar_labels.append(bar_label)
assert multibar[bar_label] is not None
for _ in range(N * BARS):
time.sleep(0.005)
bar_i = random.randrange(0, BARS)
bar_label = bar_labels[bar_i]
# Increment one of the progress bars at random
multibar[bar_label].increment()
@example
def multiple_bars_line_offset_example() -> None:
BARS = 5
N = 100
bars = [
progressbar.ProgressBar(
max_value=N,
# We add 1 to the line offset to account for the `print_fd`
line_offset=i + 1,
max_error=False,
)
for i in range(BARS)
]
# Create a file descriptor for regular printing as well
print_fd = progressbar.LineOffsetStreamWrapper(lines=0, stream=sys.stdout)
assert print_fd
# The progress bar updates, normally you would do something useful here
for _ in range(N * BARS):
time.sleep(0.005)
# Increment one of the progress bars at random
bars[random.randrange(0, BARS)].increment()
# Cleanup the bars
for bar in bars:
bar.finish()
# Add a newline to make sure the next print starts on a new line
print()
@example
def templated_shortcut_example() -> None:
for _ in progressbar.progressbar(range(10), suffix='{seconds_elapsed:.1}'):
time.sleep(0.1)
@example
def job_status_example() -> None:
with progressbar.ProgressBar(
redirect_stdout=True,
widgets=[progressbar.widgets.JobStatusBar('status')],
) as bar:
for _ in range(30):
print('random', random.random())
# Roughly 1/3 probability for each status ;)
# Yes... probability is confusing at times
if random.random() > 0.66:
bar.increment(status=True)
elif random.random() > 0.5:
bar.increment(status=False)
else:
bar.increment(status=None)
time.sleep(0.1)
@example
def with_example_stdout_redirection() -> None:
with progressbar.ProgressBar(max_value=10, redirect_stdout=True) as p:
for i in range(10):
if i % 3 == 0:
print(f'Some print statement {i:d}')
# do something
p.update(i)
time.sleep(0.1)
@example
def basic_widget_example() -> None:
widgets = [progressbar.Percentage(), progressbar.Bar()]
bar = progressbar.ProgressBar(widgets=widgets, max_value=10).start()
for i in range(10):
# do something
time.sleep(0.1)
bar.update(i + 1)
bar.finish()
@example
def color_bar_example() -> None:
widgets = [
'\x1b[33mColorful example\x1b[39m',
progressbar.Percentage(),
progressbar.Bar(marker='\x1b[32m#\x1b[39m'),
]
bar = progressbar.ProgressBar(widgets=widgets, max_value=10).start()
for i in range(10):
# do something
time.sleep(0.1)
bar.update(i + 1)
bar.finish()
@example
def color_bar_animated_marker_example() -> None:
widgets = [
# Colored animated marker with colored fill:
progressbar.Bar(
marker=progressbar.AnimatedMarker(
fill='x',
# fill='█',
fill_wrap='\x1b[32m{}\x1b[39m',
marker_wrap='\x1b[31m{}\x1b[39m',
)
),
]
bar = progressbar.ProgressBar(widgets=widgets, max_value=10).start()
for i in range(10):
# do something
time.sleep(0.1)
bar.update(i + 1)
bar.finish()
@example
def multi_range_bar_example() -> None:
markers = [
'\x1b[32m█\x1b[39m', # Done
'\x1b[33m#\x1b[39m', # Processing
'\x1b[31m.\x1b[39m', # Scheduling
' ', # Not started
]
widgets = [progressbar.MultiRangeBar('amounts', markers=markers)]
amounts = [0] * (len(markers) - 1) + [25]
with progressbar.ProgressBar(widgets=widgets, max_value=10).start() as bar:
while True:
incomplete_items = [
idx
for idx, amount in enumerate(amounts)
for _ in range(amount)
if idx != 0
]
if not incomplete_items:
break
which = random.choice(incomplete_items)
amounts[which] -= 1
amounts[which - 1] += 1
bar.update(amounts=amounts, force=True)
time.sleep(0.02)
@example
def multi_progress_bar_example(left: bool = True) -> None:
jobs = [
# Each job takes between 1 and 10 steps to complete
[0, random.randint(1, 10)]
for _ in range(25) # 25 jobs total
]
widgets = [
progressbar.Percentage(),
' ',
progressbar.MultiProgressBar('jobs', fill_left=left),
]
max_value = sum([total for progress, total in jobs])
with progressbar.ProgressBar(widgets=widgets, max_value=max_value) as bar:
while True:
incomplete_jobs = [
idx
for idx, (progress, total) in enumerate(jobs)
if progress < total
]
if not incomplete_jobs:
break
which = random.choice(incomplete_jobs)
jobs[which][0] += 1
progress = sum([progress for progress, total in jobs])
bar.update(progress, jobs=jobs, force=True)
time.sleep(0.02)
@example
def granular_progress_example() -> None:
widgets = [
progressbar.GranularBar(markers=' ▏▎▍▌▋▊▉█', left='', right='|'),
progressbar.GranularBar(markers=' ▁▂▃▄▅▆▇█', left='', right='|'),
progressbar.GranularBar(markers=' ▖▌▛█', left='', right='|'),
progressbar.GranularBar(markers=' ░▒▓█', left='', right='|'),
progressbar.GranularBar(markers=' ⡀⡄⡆⡇⣇⣧⣷⣿', left='', right='|'),
progressbar.GranularBar(markers=' .oO', left='', right=''),
]
for _ in progressbar.progressbar(list(range(100)), widgets=widgets):
time.sleep(0.03)
for _ in progressbar.progressbar(iter(range(100)), widgets=widgets):
time.sleep(0.03)
@example
def percentage_label_bar_example() -> None:
widgets = [progressbar.PercentageLabelBar()]
bar = progressbar.ProgressBar(widgets=widgets, max_value=10).start()
for i in range(10):
# do something
time.sleep(0.1)
bar.update(i + 1)
bar.finish()
@example
def file_transfer_example() -> None:
widgets = [
'Test: ',
progressbar.Percentage(),
' ',
progressbar.Bar(marker=progressbar.RotatingMarker()),
' ',
progressbar.ETA(),
' ',
progressbar.FileTransferSpeed(),
]
bar = progressbar.ProgressBar(widgets=widgets, max_value=1000).start()
for i in range(100):
# do something
time.sleep(0.01)
bar.update(10 * i + 1)
bar.finish()
@example
def custom_file_transfer_example() -> None:
class CrazyFileTransferSpeed(progressbar.FileTransferSpeed):
"""
It's bigger between 45 and 80 percent
"""
def update(self, bar):
if 45 < bar.percentage() < 80:
return 'Bigger Now ' + progressbar.FileTransferSpeed.update(
self, bar
)
else:
return progressbar.FileTransferSpeed.update(self, bar)
widgets = [
CrazyFileTransferSpeed(),
' <<<',
progressbar.Bar(),
'>>> ',
progressbar.Percentage(),
' ',
progressbar.ETA(),
]
bar = progressbar.ProgressBar(widgets=widgets, max_value=1000)
# maybe do something
bar.start()
for i in range(200):
# do something
time.sleep(0.01)
bar.update(5 * i + 1)
bar.finish()
@example
def double_bar_example() -> None:
widgets = [
progressbar.Bar('>'),
' ',
progressbar.ETA(),
' ',
progressbar.ReverseBar('<'),
]
bar = progressbar.ProgressBar(widgets=widgets, max_value=1000).start()
for i in range(100):
# do something
time.sleep(0.01)
bar.update(10 * i + 1)
bar.finish()
@example
def basic_file_transfer() -> None:
widgets = [
'Test: ',
progressbar.Percentage(),
' ',
progressbar.Bar(marker='0', left='[', right=']'),
' ',
progressbar.ETA(),
' ',
progressbar.FileTransferSpeed(),
]
bar = progressbar.ProgressBar(widgets=widgets, max_value=500)
bar.start()
# Go beyond the max_value
for i in range(100, 501, 50):
time.sleep(0.1)
bar.update(i)
bar.finish()
@example
def simple_progress() -> None:
bar = progressbar.ProgressBar(
widgets=[progressbar.SimpleProgress()],
max_value=17,
).start()
for i in range(17):
time.sleep(0.1)
bar.update(i + 1)
bar.finish()
@example
def basic_progress() -> None:
bar = progressbar.ProgressBar().start()
for i in range(10):
time.sleep(0.1)
bar.update(i + 1)
bar.finish()
@example
def progress_with_automatic_max() -> None:
# Progressbar can guess max_value automatically.
bar = progressbar.ProgressBar()
for _ in bar(range(8)):
time.sleep(0.1)
@example
def progress_with_unavailable_max() -> None:
# Progressbar can't guess max_value.
bar = progressbar.ProgressBar(max_value=8)
for _ in bar(i for i in range(8)):
time.sleep(0.1)
@example
def animated_marker() -> None:
bar = progressbar.ProgressBar(
widgets=['Working: ', progressbar.AnimatedMarker()]
)
for _ in bar(i for i in range(5)):
time.sleep(0.1)
@example
def filling_bar_animated_marker() -> None:
bar = progressbar.ProgressBar(
widgets=[
progressbar.Bar(
marker=progressbar.AnimatedMarker(fill='#'),
),
]
)
for _ in bar(range(15)):
time.sleep(0.1)
@example
def counter_and_timer() -> None:
widgets = [
'Processed: ',
progressbar.Counter('Counter: %(value)05d'),
' lines (',
progressbar.Timer(),
')',
]
bar = progressbar.ProgressBar(widgets=widgets)
for _ in bar(i for i in range(15)):
time.sleep(0.1)
@example
def format_label() -> None:
widgets = [
progressbar.FormatLabel('Processed: %(value)d lines (in: %(elapsed)s)')
]
bar = progressbar.ProgressBar(widgets=widgets)
for _ in bar(i for i in range(15)):
time.sleep(0.1)
@example
def animated_balloons() -> None:
widgets = ['Balloon: ', progressbar.AnimatedMarker(markers='.oO@* ')]
bar = progressbar.ProgressBar(widgets=widgets)
for _ in bar(i for i in range(24)):
time.sleep(0.1)
@example
def animated_arrows() -> None:
# You may need python 3.x to see this correctly
try:
widgets = ['Arrows: ', progressbar.AnimatedMarker(markers='←↖↑↗→↘↓↙')]
bar = progressbar.ProgressBar(widgets=widgets)
for _ in bar(i for i in range(24)):
time.sleep(0.1)
except UnicodeError:
sys.stdout.write('Unicode error: skipping example')
@example
def animated_filled_arrows() -> None:
# You may need python 3.x to see this correctly
try:
widgets = ['Arrows: ', progressbar.AnimatedMarker(markers='◢◣◤◥')]
bar = progressbar.ProgressBar(widgets=widgets)
for _ in bar(i for i in range(24)):
time.sleep(0.1)
except UnicodeError:
sys.stdout.write('Unicode error: skipping example')
@example
def animated_wheels() -> None:
# You may need python 3.x to see this correctly
try:
widgets = ['Wheels: ', progressbar.AnimatedMarker(markers='◐◓◑◒')]
bar = progressbar.ProgressBar(widgets=widgets)
for _ in bar(i for i in range(24)):
time.sleep(0.1)
except UnicodeError:
sys.stdout.write('Unicode error: skipping example')
@example
def format_label_bouncer() -> None:
widgets = [
progressbar.FormatLabel('Bouncer: value %(value)d - '),
progressbar.BouncingBar(),
]
bar = progressbar.ProgressBar(widgets=widgets)
for _ in bar(i for i in range(100)):
time.sleep(0.01)
@example
def format_label_rotating_bouncer() -> None:
widgets = [
progressbar.FormatLabel('Animated Bouncer: value %(value)d - '),
progressbar.BouncingBar(marker=progressbar.RotatingMarker()),
]
bar = progressbar.ProgressBar(widgets=widgets)
for _ in bar(i for i in range(18)):
time.sleep(0.1)
@example
def with_right_justify() -> None:
with progressbar.ProgressBar(
max_value=10, term_width=20, left_justify=False
) as progress:
assert progress.term_width is not None
for i in range(10):
progress.update(i)
@example
def exceeding_maximum() -> None:
with (
progressbar.ProgressBar(max_value=1) as progress,
contextlib.suppress(ValueError),
):
progress.update(2)
@example
def reaching_maximum() -> None:
progress = progressbar.ProgressBar(max_value=1)
with contextlib.suppress(RuntimeError):
progress.update(1)
@example
def stdout_redirection() -> None:
with progressbar.ProgressBar(redirect_stdout=True) as progress:
print('', file=sys.stdout)
progress.update(0)
@example
def stderr_redirection() -> None:
with progressbar.ProgressBar(redirect_stderr=True) as progress:
print('', file=sys.stderr)
progress.update(0)
@example
def rotating_bouncing_marker() -> None:
widgets = [progressbar.BouncingBar(marker=progressbar.RotatingMarker())]
with progressbar.ProgressBar(
widgets=widgets, max_value=20, term_width=10
) as progress:
for i in range(20):
time.sleep(0.1)
progress.update(i)
widgets = [
progressbar.BouncingBar(
marker=progressbar.RotatingMarker(), fill_left=False
)
]
with progressbar.ProgressBar(
widgets=widgets, max_value=20, term_width=10
) as progress:
for i in range(20):
time.sleep(0.1)
progress.update(i)
@example
def incrementing_bar() -> None:
bar = progressbar.ProgressBar(
widgets=[
progressbar.Percentage(),
progressbar.Bar(),
],
max_value=10,
).start()
for _ in range(10):
# do something
time.sleep(0.1)
bar += 1
bar.finish()
@example
def increment_bar_with_output_redirection() -> None:
widgets = [
'Test: ',
progressbar.Percentage(),
' ',
progressbar.Bar(marker=progressbar.RotatingMarker()),
' ',
progressbar.ETA(),
' ',
progressbar.FileTransferSpeed(),
]
bar = progressbar.ProgressBar(
widgets=widgets, max_value=100, redirect_stdout=True
).start()
for i in range(10):
# do something
time.sleep(0.01)
bar += 10
print('Got', i)
bar.finish()
@example
def eta_types_demonstration() -> None:
widgets = [
progressbar.Percentage(),
' ETA: ',
progressbar.ETA(),
' Adaptive : ',
progressbar.AdaptiveETA(),
' Smoothing(a=0.1): ',
progressbar.SmoothingETA(smoothing_parameters=dict(alpha=0.1)),
' Smoothing(a=0.9): ',
progressbar.SmoothingETA(smoothing_parameters=dict(alpha=0.9)),
' Absolute: ',
progressbar.AbsoluteETA(),
' Transfer: ',
progressbar.FileTransferSpeed(),
' Adaptive T: ',
progressbar.AdaptiveTransferSpeed(),
' ',
progressbar.Bar(),
]
bar = progressbar.ProgressBar(widgets=widgets, max_value=500)
bar.start()
for i in range(500):
if i < 100:
time.sleep(0.02)
elif i > 400:
time.sleep(0.1)
else:
time.sleep(0.01)
bar.update(i + 1)
bar.finish()
@example
def adaptive_eta_without_value_change() -> None:
# Testing progressbar.AdaptiveETA when the value doesn't actually change
bar = progressbar.ProgressBar(
widgets=[
progressbar.AdaptiveETA(),
progressbar.AdaptiveTransferSpeed(),
],
max_value=2,
poll_interval=0.0001,
)
bar.start()
for _ in range(100):
bar.update(1)
time.sleep(0.1)
bar.finish()
@example
def iterator_with_max_value() -> None:
# Testing using progressbar as an iterator with a max value
bar = progressbar.ProgressBar()
for _ in bar(iter(range(100)), 100):
# iter range is a way to get an iterator in both python 2 and 3
time.sleep(0.01)
@example
def eta() -> None:
widgets = [
'Test: ',
progressbar.Percentage(),
' | ETA: ',
progressbar.ETA(),
' | AbsoluteETA: ',
progressbar.AbsoluteETA(),
' | AdaptiveETA: ',
progressbar.AdaptiveETA(),
]
bar = progressbar.ProgressBar(widgets=widgets, max_value=50).start()
for i in range(50):
time.sleep(0.1)
bar.update(i + 1)
bar.finish()
@example
def variables() -> None:
# Use progressbar.Variable to keep track of some parameter(s) during
# your calculations
widgets = [
progressbar.Percentage(),
progressbar.Bar(),
progressbar.Variable('loss'),
', ',
progressbar.Variable('username', width=12, precision=12),
]
with progressbar.ProgressBar(max_value=100, widgets=widgets) as bar:
min_so_far = 1
for i in range(100):
time.sleep(0.01)
val = random.random()
if val < min_so_far:
min_so_far = val
bar.update(i, loss=min_so_far, username='Some user')
@example
def user_variables() -> None:
tasks = {
'Download': [
'SDK',
'IDE',
'Dependencies',
],
'Build': [
'Compile',
'Link',
],
'Test': [
'Unit tests',
'Integration tests',
'Regression tests',
],
'Deploy': [
'Send to server',
'Restart server',
],
}
num_subtasks = sum(len(x) for x in tasks.values())
with progressbar.ProgressBar(
prefix='{variables.task} >> {variables.subtask}',
variables={'task': '--', 'subtask': '--'},
max_value=10 * num_subtasks,
) as bar:
for tasks_name, subtasks in tasks.items():
for subtask_name in subtasks:
for _ in range(10):
bar.update(
bar.value + 1, task=tasks_name, subtask=subtask_name
)
time.sleep(0.1)
@example
def format_custom_text() -> None:
format_custom_text = progressbar.FormatCustomText(
'Spam: %(spam).1f kg, eggs: %(eggs)d',
dict(
spam=0.25,
eggs=3,
),
)
bar = progressbar.ProgressBar(
widgets=[
format_custom_text,
' :: ',
progressbar.Percentage(),
]
)
for i in bar(range(25)):
format_custom_text.update_mapping(eggs=i * 2)
time.sleep(0.1)
@example
def simple_api_example() -> None:
bar = progressbar.ProgressBar(widget_kwargs=dict(fill='█'))
for _ in bar(range(200)):
time.sleep(0.02)
@example
def eta_on_generators():
def gen():
for _ in range(200):
yield None
widgets = [
progressbar.AdaptiveETA(),
' ',
progressbar.ETA(),
' ',
progressbar.Timer(),
]
bar = progressbar.ProgressBar(widgets=widgets)
for _ in bar(gen()):
time.sleep(0.02)
@example
def percentage_on_generators():
def gen():
for _ in range(200):
yield None
widgets = [
progressbar.Counter(),
' ',
progressbar.Percentage(),
' ',
progressbar.SimpleProgress(),
' ',
]
bar = progressbar.ProgressBar(widgets=widgets)
for _ in bar(gen()):
time.sleep(0.02)
def test(*tests) -> None:
if tests:
no_tests = True
for example in examples:
for test in tests:
if test in example.__name__:
example()
no_tests = False
break
if no_tests:
for example in examples:
print('Skipping', example.__name__)
else:
for example in examples:
example()
if __name__ == '__main__':
try:
test(*sys.argv[1:])
except KeyboardInterrupt:
sys.stdout.write('\nQuitting examples.\n')