What should be the amateur version of progress - a gress? The gress library provide highly customizable text-based progress monitor for Python. The inspiration for this library came from the original work of Nilton Volpato, but it was recreated from scratch to make it easier to set up and use.
import time
from gress import gress
# counting sheep
for i in gress(range(100)):
time.sleep(0.1)
# output during processing
# 81 of 100 (81%) █████████████████████████████-------- 00:00:08 | 9.54/s | ETA 1s
import time
from gress import gress
# init herd
sheep = (i for i in range(100))
# counting sheep
for i in gress(sheep, maximum=100):
time.sleep(0.1)
# output during processing
# 46 of 100 (46%) █████████████████-------------------- 00:00:04 | 9.66/s | ETA 5s
import time
from gress import gress
# counting sheep
for i in gress(range(100), "{percent} % {bar} ETA {autoeta}", size=40):
time.sleep(0.1)
# output during processing
# 46 % ████████████---------------- ETA 5s
import time
import gress
# init herd
sheep = 100
# init bar
bar = gress.Bar("Counting: {count} of {maximum} ({percent}%) {bar} {speed}/s | {timer} | ETA {autoeta}", maximum=sheep)
# counting sheep
for i in bar(range(sheep)):
time.sleep(0.1)
# write final report
bar.write("All {count} sheep counted in {autotimer} with the average rate of {speed}/s.")
# output during processing
# Counting: 56 of 100 (56%) ███████████████------------ 9.63/s | 00:00:05 | ETA 4s
# output after processing
# All 100 sheep counted in 10s with the average rate of 9.65/s.
import time
import gress
# init herd
sheep = 100
# init bar
bar = gress.Bar("Counting: {count} of {maximum} ({percent}%) {bar} {speed}/s | {timer} | ETA {autoeta}", maximum=sheep)
bar.start()
# counting sheep
sleep = 0.1
for i in range(sheep):
time.sleep(sleep)
# increment progress
bar += 1
# count slower while sleeping (50 sheep and more)
if bar.current == sheep / 2:
bar.write("{time} I should sleep now, so I'm counting slower!")
sleep *= 2
# finish and make final report
bar.finish("{time} All {count} sheep counted in {autotimer} with the average rate of {speed}/s.")
# output during processing
# 2022-10-01 21:12:13.565873 I should sleep now, so I'm counting slower!
# Counting: 77 of 100 (77%) ████████████████████------ 4.95/s | 00:00:10 | ETA 4s
# output after processing
# 2022-10-01 21:12:13.565873 I should sleep now, so I'm counting slower!
# 2022-10-01 21:12:23.478325 All 100 sheep counted in 15s with the average rate of 6.47/s.
The best way to monitor progress is to initialize the Bar object with a custom template, using predefined widgets and continuously increase its value (see the example above). Although this should cover most of the use cases, there are many ways to go deeper to customize the main progress bar or individual widgets.
widgets: (Widget,) or str
Collection of widgets to display on each update. The widget can be one of
the many predefined widgets, simple string to show or any class derived from
the Widget base. The widgets can also be provided using a template, where
the widgets are specified by a name in curly brackets
(e.g. 'Processed: {count} ETA: {eta}').
minimum: int
Minimum progress value or count.
maximum: int
Maximum progress value or count.
size: int
Number of characters available to display the progress.
refresh: float
Minimum number of seconds between individual updates to be displayed.
sample: int
Number of last sample to keep for adaptive widgets like ETA
or speed. Such widgets are calculating progress from last
measurements instead of overall progress.
output: any
Custom output to which all the progress and messages are writen. This must support
'write' and 'flush' method calls.
By template - This is probably the most convenient method of widgets initialization. It is based on recognizing predefined or registered widgets by their unique tags within a single template string. The widgets are specified using the {tag} syntax.
bar = gress.Bar("Counting: {count} of {maximum} sheep. Ready in {autoeta}.", maximum=100)
By widgets - If none of the predefined widgets suits your needs, custom instances can be provided directly.
bar = gress.Bar(
"Counting: ",
gress.Property("current", "{:03}"), " of ", gress.Property("maximum"),
" sheep. Ready in ",
gress.ETA("{s}s"),
".",
maximum=100)
By combination - Any template can be combined with custom widgets instances.
bar = gress.Bar("Counting: ", gress.Property("current", "{:03}"), " of {maximum} sheep. Ready in {autoeta}.", maximum=100)
By custom widgets within template - Custom widgets instances can also be registered under unique tag and used directly within a template.
bar = gress.Bar("Counting: {mycount} of {maximum} sheep. Ready in {autoeta}.", maximum=100)
bar.register("mycount", gress.Property("current", "{:03}"))
The progress bar can be used directly as an iterable by providing valid source. In such scenario the increment is done automatically for every iteration call.
# using collection
for i in bar([1,2,3,4,5]):
do_something()
# using range
for i in bar(range(100)):
do_something()
# using iterable
items = (i for i in range(100))
for i in bar(items, maximum=100):
do_something()
Depending on particular situation, different types of manual progress update may be useful. Upon every update the bar decides whether the displayed progress should be refreshed or not. This can be influenced by the refresh argument of the bar itself.
# by increment
step = 10
for i in range(0, 100, step):
do_something()
bar += step
# by increment method
step = 10
for i in range(0, 100, step):
do_something()
bar.increase(step)
# to specific value
step = 10
for i in range(0, 100, step):
do_something()
bar.update((i+1)*step)
Any message can be writen during processing using the bar .write() method. It can be as simple as a single string or as complex as a combination of multiple widgets. Depending on the permanent argument, the message can be displayed permanently of removed later by next progress update.
bar.write("{time} I should sleep now, so I'm counting slower!")
To inform the bar that the progress has finished just call the finish() method. This stops the elapsed time to be increase any further and prints the final state of the progress. This behavior can be modified by providing custom widgets to be displayed and writen permanently. In case the progress bar is used as iterable, it silently finishes itself automatically when iteration stops.
bar.finish("{time} All {count} sheep counted in {autotimer} with the average rate of {speed}/s.")
There are multiple widgets types available covering various aspects of processing from simple count or animated progress bar up to estimated time of the process to finish. As mentioned above, they can be used as custom instances with specific settings or many of the predefined widgets can be used directly within a template string.
The Property widget displays specified progress value using given formatting template. Optionally, if unit prefixes are provided, the value is scaled automatically and corresponding unit prefix is added (e.g. 1500 vs. 1.50 k). There are predefined prefixes available like PREFIXES - typically used for data scaling. Note that the power multiplier can be specified as well (e.g. 1024 for data).
name: str
Name of the progress bar property to show. (E.g. "current", "minimum", "maximum".)
template: str
Custom template to be used to format the property value (e.g. "{:.2f}").
prefixes: (str,) or None
Units prefix for each power (e.g. gress.PREFIXES).
step: int
Multiplier of the power (e.g. 1000 or 1024).
- PREFIXES = ("", "k", "M", "G", "T", "P", "E", "Z", "Y")
- {current} : Property(name="current", template=None)
- {minimum} : Property(name="minimum", template=None)
- {maximum} : Property(name="maximum", template=None)
- {min} : Property(name="minimum", template=None)
- {max} : Property(name="maximum", template=None)
- {count} : Property(name="current", template="{:.0f}")
- {percent} : Property(name="percent", template="{:.0f}")
- {data} : Property(name="current", template="{:.2f}", prefixes=PREFIXES, step=1024)
- {dataminimum} : Property(name="minimum", template="{:.2f}", prefixes=PREFIXES, step=1024)
- {datamaximum} : Property(name="maximum", template="{:.2f}", prefixes=PREFIXES, step=1024)
- {datamin} : Property(name="minimum", template="{:.2f}", prefixes=PREFIXES, step=1024)
- {datamax} : Property(name="maximum", template="{:.2f}", prefixes=PREFIXES, step=1024)
- {sci} : Property(name="current", template="{:.2f}", prefixes=PREFIXES, step=1000)
- {sciminimum} : Property(name="minimum", template="{:.2f}", prefixes=PREFIXES, step=1000)
- {scimaximum} : Property(name="maximum", template="{:.2f}", prefixes=PREFIXES, step=1000)
- {scimin} : Property(name="minimum", template="{:.2f}", prefixes=PREFIXES, step=1000)
- {scimax} : Property(name="maximum", template="{:.2f}", prefixes=PREFIXES, step=1000)
The Time widget displays current time according to specified template, which should follow the standard datetime notation (e.g. "%Y-%m-%d %H:%M:%S").
template: str or None
Custom template to be used to format the time. The template should use standard
datetime notation (e.g. "%Y-%m-%d %H:%M:%S"). If set to None, full time is shown.
- {time} : Time()
The Timer widget displays current progress elapsed time, according to specified template or formatted automatically as needed. The template can use "dhms" characters to format individual parts (e.g. "{m:02}:{s:02}"). Optionally, the time units can be displayed if automatic formatting is used.
template: str or None
Custom template to be used to format the time. The template can use "dhms" characters
to format individual parts (e.g. "{m:02}:{s:02}"). If set to None, remaining time is
formatted automatically.
units: bool
If se to True and no template is provided, remaining time is shown with units.
- TIME_ABS = "%Y-%m-%d %H:%M:%S"
- TIME_DHMS = "{d}:{h:02}:{m:02}:{s:02}"
- TIME_HMS = "{h:02}:{m:02}:{s:02}"
- TIME_MS = "{m:02}:{s:02}"
- TIME_S = "{s}"
- TIME_DHMS_U = "{d}d {h}h {m}m {s}s"
- TIME_HMS_U = "{h}h {m}m {s}s"
- TIME_MS_U = "{m}m {s}s"
- TIME_S_U = "{s}s"
- {timer} : Timer(template=TIME_HMS)
- {autotimer} : Timer(template=None, units=True)
The ETA widget displays current progress estimated time of finish, according to specified template or formatted automatically as needed. If absolute time should be displayed, the template should use the standard datetime notation (e.g. "%Y-%m-%d %H:%M:%S"). For remaining time the template can use "dhms" characters to format individual parts (e.g. "{m:02}:{s:02}"). Optionally, the time units can be displayed if automatic formatting is used.
The time is by default calculated using several latest progress updates, unless the adaptive parameter is set to False. In such case the whole elapsed time and progress is used.
template: str or None
Custom template to be used to format the time. For absolute ETA the template
should use the standard datetime notation (e.g. "%Y-%m-%d %H:%M:%S"). For relative
ETA the template can use "dhms" characters to format individual parts
(e.g. "{m:02}:{s:02}"). If set to None, remaining time is formatted automatically.
units: bool
If se to True and no template is provided, remaining time is shown with units.
absolute: bool
If set to True, remaining time is shown as the absolute time of expected finish,
otherwise the remaining time is shown.
adaptive: bool
If set to True, the speed is calculated from last N updates only, otherwise
the whole progress is used. Number of updates depends on the progress bar settings.
- {eta} : ETA(template=TIME_HMS, absolute=False, adaptive=True)
- {autoeta} : ETA(template=None, units=True, absolute=False, adaptive=True)
- {abseta"} : ETA(template=TIME_ABS, absolute=True, adaptive=True)
The Speed widgets displays current progress speed, according to specified template. Optionally, if unit prefixes are provided, the value is scaled automatically and corresponding unit prefix is added (e.g. 1.5 MBps). There are predefined prefixes available like PREFIXES - typically used for data scaling. Note that the power multiplier can be specified as well (e.g. 1024 for data).
The speed is by default calculated using several latest progress updates, unless the adaptive parameter is set to False. In such case the whole elapsed time and progress is used.
template: str
Custom template to be used to format the speed value.
prefixes: (str,) or None
Units prefix for each power (e.g. gress.PREFIXES).
step: int
Multiplier of the power (e.g. 1000 or 1024).
adaptive: bool
If set to True, the speed is calculated from last N updates only, otherwise
the whole progress is used. Number of updates depends on the progress bar settings.
- {speed} : Speed(template="{:.2f}", prefixes=None, adaptive=True)
- {bps} : Speed(template="{:.2f}", prefixes=PREFIXES, step=1024, adaptive=True)
- {dataspeed} : Speed(template="{:.2f}", prefixes=PREFIXES, step=1024, adaptive=True)
- {scispeed} : Speed(template="{:.2f}", prefixes=PREFIXES, step=1000, adaptive=True)
The Gauge widget displays current progress as a proportionally filled bar. The characters used can be fully customized to achieve desired look. If the size is not specified, it fills all available space automatically. In case the parent progress does not specify the maximum value, the marker character just bounces back a forth instead of filling the bar.
marker: str
Character used to show current progress (e.g. "=").
left: str
Character used for the left edge (e.g. "[").
right: str
Character used for the right edge (e.g. "]").
fill: str
Character used to fill remaining space (e.g. "-").
tip: str
Character used for the progress tip (e.g. ">").
size: int or None
Desired length of the gauge. If set to None, whole available space will be used.
- {gauge} : Gauge(marker="|", left="|", right="|", fill="-", tip="")
- {bar} : Gauge(marker="█", left="", right="", fill="-", tip="")
The Spin widget displays current progress as animated character. It is defined by a sequence of characters to use, each update displays the next available character. By setting the widget as relative, available characters are mapped to cover the whole progress range, otherwise the widget circles through them.
markers: str
Individual characters to animate (e.g. "→↘↓↙←↖↑↗" or simply grass.ARROW).
fin: str
Final character after process finished. If not specified, the last character
of given markers is used.
relative: bool
If set to True, characters are distributed equally across full progress.
If set to False, next character is used for every update.
- ARROW = "→↘↓↙←↖↑↗"
- CIRCLE = " .oO"
- DOTS = " ⡀⡄⡆⡇⣇⣧⣷⣿"
- FADE = " ░▒▓█"
- HBAR = " ▏▎▍▌▋▊▉█"
- LINE = "⎽⎼⎻⎺⎻⎼"
- MOON = "◑◒◐◓"
- PIE = "○◔◑◕●"
- PIXEL = "⣾⣷⣯⣟⡿⢿⣻⣽"
- SNAKE = " ▖▌▛█"
- STAR = "-\|/"
- VBAR = " ▁▂▃▄▅▆▇█"
- {arrow} : Spin(markers=ARROW, fin="↑", relative=False)
- {circle} : Spin(markers=CIRCLE, relative=False)
- {dots} : Spin(markers=DOTS, relative=False)
- {fade} : Spin(markers=FADE, relative=False)
- {hbar} : Spin(markers=HBAR, relative=False)
- {line} : Spin(markers=LINE, relative=False)
- {moon} : Spin(markers=MOON, relative=False)
- {pie} : Spin(markers=PIE, relative=False)
- {pixel} : Spin(markers=PIXEL, fin="⣿", relative=False)
- {snake} : Spin(markers=SNAKE, relative=False)
- {spin} : Spin(markers=STAR, fin="|", relative=False)
- {star} : Spin(markers=STAR, fin="|", relative=False)
- {vbar} : Spin(markers=VBAR, relative=False)
- {reldots} : Spin(markers=DOTS, relative=True)
- {relfade} : Spin(markers=FADE, relative=True)
- {relhbar} : Spin(markers=HBAR, relative=True)
- {relpie} : Spin(markers=PIE, relative=True)
- {relsnake} : Spin(markers=SNAKE, relative=True)
- {relvbar} : Spin(markers=BAR, relative=True)
The Callback widget provides a special type of widgets to displays custom variables within the progress bar retrieved by specified callback function. The callback is typically specified as a lambda function with no input parameters, returning the final formatted custom value.
callback: callable
Custom function to be used to retrieve and format the custom value.
The Variable widget provides a special type of widgets to displays custom variables within the progress bar. Optionally, the formatting template can be provided to format the value automatically into string.
value: any
Current variable value.
template: str
Custom template to be used to format the value (e.g. "{:.2f}").
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.