A new kind of Progress Bar, with real-time throughput, ETA, and very cool animations!
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Core progress bar functionality providing context managers, iterator adapters, and comprehensive progress monitoring capabilities. Supports multiple modes of operation including automatic counting, manual percentage control, and unknown total scenarios.
The primary interface for creating progress bars. Returns a context manager that yields a bar handle for controlling progress updates, text messages, and monitoring.
def alive_bar(total: Optional[int] = None, *, calibrate: Optional[int] = None, **options: Any):
"""
Create an alive progress bar context manager.
Parameters:
- total (Optional[int]): Expected total count. If None, creates unknown mode bar
- calibrate (Optional[int]): Maximum theoretical throughput for animation calibration
- **options: Configuration options (see Configuration documentation)
Returns:
Context manager yielding AliveBarHandle object
Raises:
- TypeError: If total is not an integer
- ValueError: If configuration options are invalid
"""Known Total (Definite Mode):
with alive_bar(1000, title='Processing Items') as bar:
for i in range(1000):
# do work
bar() # advance by 1
# Or advance by different amounts
for batch in batches:
process_batch(batch)
bar(len(batch)) # advance by batch sizeUnknown Total (Unknown Mode):
with alive_bar(title='Processing') as bar:
for item in some_generator():
process_item(item)
bar() # increment counterManual Percentage Mode:
with alive_bar(manual=True, title='Processing') as bar:
for i, item in enumerate(items):
process_item(item)
bar(i / len(items)) # set percentage directlyWraps iterables to automatically track progress without manual bar() calls. Infers total from iterable length when possible and provides the same bar handle interface.
def alive_it(it: Collection[T], total: Optional[int] = None, *,
finalize: Callable[[Any], None] = None,
calibrate: Optional[int] = None, **options: Any) -> Iterable[T]:
"""
Iterator adapter that automatically tracks progress.
Parameters:
- it: Input iterable to be processed
- total (Optional[int]): Override total count (use 0 to force unknown mode)
- finalize (Optional[Callable]): Function called when iteration completes
- calibrate (Optional[int]): Maximum theoretical throughput for animation calibration
- **options: Configuration options (see Configuration documentation)
Returns:
Generator that yields items from input iterable
Raises:
- UserWarning: If manual=True is specified (not supported in iterator mode)
"""Basic Iterator Adaptation:
items = range(1000)
for item in alive_it(items, title='Processing'):
process_item(item)
# Progress automatically trackedWith Finalization Callback:
def finalize_processing(bar):
bar.title = 'Processing Complete'
bar.text = f'Processed {bar.current} items'
for item in alive_it(items, finalize=finalize_processing, receipt_text=True):
process_item(item)Force Unknown Mode:
# Even if iterable has length, force unknown mode
for item in alive_it(items, total=0):
process_item(item)The object returned by alive_bar context manager, providing methods and properties for controlling the progress bar.
def __call__(self, count: int = 1, *, skipped: bool = False) -> None:
"""
Advance the progress bar.
Parameters:
- count (int): Amount to advance (can be negative in definite mode)
- skipped (bool): Whether this count represents skipped items (for resumption)
"""Usage Examples:
with alive_bar(1000) as bar:
# Advance by 1 (default)
bar()
# Advance by specific amount
bar(50)
# Skip already processed items (for resumption)
bar(100, skipped=True)
# Go backwards (definite mode only)
bar(-10)@property
def current(self) -> Union[int, float]:
"""Current count or percentage value."""
@property
def monitor(self) -> str:
"""Current monitor text (formatted count/total/percent)."""
@property
def rate(self) -> str:
"""Current processing rate text."""
@property
def eta(self) -> str:
"""Current ETA (Estimated Time of Arrival) text."""
@property
def elapsed(self) -> float:
"""Elapsed time in seconds since bar started."""
@property
def receipt(self) -> str:
"""Final receipt string (available even after completion)."""@property
def text(self) -> Optional[str]:
"""Situational message displayed within or below the bar."""
@text.setter
def text(self, value: Optional[str]) -> None:
"""Set situational message."""
@property
def title(self) -> Optional[str]:
"""Bar title (can be changed even after completion)."""
@title.setter
def title(self, value: Optional[str]) -> None:
"""Set bar title."""Usage Examples:
with alive_bar(1000, title='Initial Title') as bar:
for i in range(1000):
bar.text = f'Processing item {i}'
process_item(i)
bar()
# Change title even after completion
bar.title = 'Processing Complete'def pause(self):
"""
Context manager to pause the progress bar.
Temporarily stops the bar, clears the display, and returns control
to the Python prompt. Resumes seamlessly when context exits.
Returns:
Context manager for pausing the bar
"""Usage Example:
with alive_bar(1000) as bar:
for i in range(500):
process_item(i)
bar()
# Pause for manual intervention
with bar.pause():
print("Bar is paused - doing manual work")
manual_fixes()
input("Press Enter to continue...")
# Bar resumes automatically
for i in range(500, 1000):
process_item(i)
bar()Support for resuming long-running processes by marking already-processed items as skipped, preventing ETA calculation issues.
# Resume from known position
with alive_bar(10000) as bar:
bar(5000, skipped=True) # Mark first 5000 as already done
for i in range(5000, 10000):
process_item(i)
bar()
# Resume with scattered completion
processed_items = get_already_processed()
with alive_bar(len(all_items)) as bar:
for item in all_items:
if item.id in processed_items:
bar(skipped=True)
continue
process_item(item)
bar()# Common exceptions
try:
with alive_bar("invalid") as bar: # TypeError
pass
except TypeError as e:
print(f"Invalid total type: {e}")
try:
with alive_bar(100, invalid_option=True) as bar: # ValueError
pass
except ValueError as e:
print(f"Invalid configuration: {e}")
# Keyboard interruption
try:
with alive_bar(1000) as bar:
for i in range(1000):
bar()
except KeyboardInterrupt:
print("Processing interrupted by user")Install with Tessl CLI
npx tessl i tessl/pypi-alive-progress