Skip to content

lama2923/smartbar

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 

Repository files navigation

SmartBar

PyPI GitHub Repo

SmartBar is a powerful, automatic, and extensible progress bar library for Python, built with smart I/O tracking and multi-threading support.
It provides real-time progress, ETA, speed tracking, and works seamlessly with file and network I/O using with blocks — no manual .update() needed.


Features

  • Thread-safe and supports concurrent usage
  • Supports multiple bars simultaneously
  • Automatically wraps open(), requests.get(), and aiohttp
  • Tracks both reading and writing operations
  • Smart speed and ETA calculation (combines recent + average)
  • Fully customizable output and bar style
  • Pause, resume, ignore, and manual update support
  • Works with with and async with contexts

Installation

pip install smartbar

Basic Example

from smartbar import SmartBar
import requests

with SmartBar("Downloading", length=40) as bar:
    r = requests.get("https://example.com/file", stream=True)
    for chunk in r.iter_content(1024):
        pass  # progress is auto-tracked

Custom Style & Live Animation

from smartbar import SmartBar
import requests
import time

BAR1 = "%(DESC). \033[48;5;214m[%(BAR)]\033[0m %(CUR)/%(TOTAL) (%(PERCENT)) | %(SPEED) | ETA: %(ETA)"
BAR2 = "%(DESC).. \033[48;5;214m[%(BAR)]\033[0m %(CUR)/%(TOTAL) (%(PERCENT)) | %(SPEED) | ETA: %(ETA)"
BAR3 = "%(DESC)... \033[48;5;214m[%(BAR)]\033[0m %(CUR)/%(TOTAL) (%(PERCENT)) | %(SPEED) | ETA: %(ETA)"

url = "https://download.samplelib.com/mp4/sample-20s.mp4"

with SmartBar("Downloading", custom_bar_output=BAR1) as bar:
    response = requests.get(url, stream=True)
    with open("video.mp4", "wb") as f:
        stime = time.time()
        for chunk in response.iter_content(chunk_size=8192):
            if chunk:
                f.write(chunk)
            if time.time() - stime > 1:
                # Animate bar every second
                bar.custom_bar_output = BAR2 if bar.custom_bar_output == BAR1 else (
                    BAR3 if bar.custom_bar_output == BAR2 else BAR1
                )
                stime = time.time()

Manual Progress (Disable Auto Tracking)

import time
from smartbar import SmartBar

BAR1 = "%(DESC). {} SEC \033[48;5;214m[%(BAR)]\033[0m %(CUR)/%(TOTAL) (%(PERCENT)) | %(SPEED) | ETA: %(ETA)"
BAR2 = "%(DESC).. {} SEC \033[48;5;214m[%(BAR)]\033[0m %(CUR)/%(TOTAL) (%(PERCENT)) | %(SPEED) | ETA: %(ETA)"
BAR3 = "%(DESC)... {} SEC \033[48;5;214m[%(BAR)]\033[0m %(CUR)/%(TOTAL) (%(PERCENT)) | %(SPEED) | ETA: %(ETA)"

SEC = 10

with SmartBar("Waiting", auto_bar=False, mode="items") as bar:
    bar.total = SEC
    start = time.time()
    last = time.time()
    while True:
        now = time.time()
        if now - last > 1:
            elapsed = int(now - start)
            seconds_left = max(0, SEC - elapsed)

            if bar.custom_bar_output == BAR1:
                bar.custom_bar_output = BAR2.format(seconds_left)
            elif bar.custom_bar_output == BAR2:
                bar.custom_bar_output = BAR3.format(seconds_left)
            else:
                bar.custom_bar_output = BAR1.format(seconds_left)

            bar.add(now - last)
            last = now

        if bar.current >= bar.total:
            break

Async Support

import aiohttp
import asyncio
from smartbar import SmartBar

async def download():
    async with SmartBar("Async Download") as bar:
        async with aiohttp.ClientSession() as session:
            async with session.get("https://example.com") as resp:
                async for chunk in resp.content.iter_chunked(1024):
                    pass  # progress auto-tracked

asyncio.run(download())

Pause, Resume & Ignore

from smartbar import SmartBar
import requests

with SmartBar("Download") as bar:
    r = requests.get("https://example.com/file", stream=True)

    bar.pause()
    # Do something non-tracked...
    bar.resume()

    bar.ignore(r)  # disables tracking for this object

Format Variables

You can customize the output bar using these placeholders:

Placeholder Meaning
%(DESC) Bar description
%(BAR) The visual progress bar
%(CUR) Current value
%(TOTAL) Total expected value
%(PERCENT) Percentage completed
%(SPEED) Transfer speed
%(ETA) Estimated time remaining

Example:
"%(BAR)"[#######.......]

bar_style

with SmartBar("Waiting", auto_bar=False, mode="items", bar_style="simple", style=r"——") as bar: 
    pass

custom_bar_style

example_style = {  # [Foreground, Background]
    "BAR": {
        "+": [0xFFFFFF, 0x000000],
        "-": [0x888888, None],
    },
    "DESC": [0xAAAAAA, None],
    "CUR": [0xAAAAAA, None],
    "TOTAL": [0xAAAAAA, None],
    "PERCENT": [0xAAAAAA, None],
    "SPEED": [0xAAAAAA, None],
    "ETA": [0xAAAAAA, None],
}

with SmartBar("Waiting", auto_bar=False, mode="items", custom_bar_style=example_style, style=r"——") as bar:
    pass

License

MIT


Author

lama2923
GitHub: https://github.com/lama2923


Iterable Mode (for usage)

SmartBar can also be used directly inside a for loop for iterating over an iterable, such as a list, generator, or file.

from smartbar import SmartBar
import time

data = range(100)

for item in SmartBar(data, desc="Processing", length=30):
    time.sleep(0.05)  # simulate work

This usage automatically tracks iteration progress and provides ETA and speed based on iteration rate.


Releases

No releases published

Packages

No packages published

Languages