<div align=center>
<image src="https://github.com/user-attachments/assets/ce85bc38-6741-4a86-8ca9-71c13c7fc563" width=50%>
</image>
<h1>LogBar</h1>
A unified logger, table renderer, and progress bar utility with zero runtime dependencies.
</div>
<p align="center" >
<a href="https://github.com/ModelCloud/LogBar/releases" style="text-decoration:none;"><img alt="GitHub release" src="https://img.shields.io/github/release/ModelCloud/LogBar.svg"></a>
<a href="https://pypi.org/project/logbar/" style="text-decoration:none;"><img alt="PyPI - Version" src="https://img.shields.io/pypi/v/logbar"></a>
<a href="https://pepy.tech/projects/logbar" style="text-decoration:none;"><img src="https://static.pepy.tech/badge/logbar" alt="PyPI Downloads"></a>
<a href="https://github.com/ModelCloud/LogBar/blob/main/LICENSE"><img src="https://img.shields.io/pypi/l/logbar" alt="License"></a>
<a href="https://huggingface.co/modelcloud/"><img src="https://img.shields.io/badge/Hugging%20Face-ModelCloud-%23ff8811.svg"></a>
</p>
# Features
- Shared singleton logger with per-level colorized output.
- `once` helpers prevent duplicate log spam automatically.
- Stackable progress bars that stay anchored while your logs flow freely.
- Built-in styling for progress bar fills, colors, gradients, and head glyphs.
- Animated progress titles with a subtle sweeping highlight.
- Column-aware table printer with spans, width hints, and `fit` sizing.
- Zero dependencies; works anywhere Python runs.
# Installation
```bash
pip install logbar
```
LogBar works out-of-the-box with CPython 3.8+ on Linux, macOS, and Windows terminals.
# Quick Start
```py
import time
from logbar import LogBar
log = LogBar.shared()
log.info("hello from logbar")
log.info.once("this line shows once")
log.info.once("this line shows once") # silently skipped
for _ in log.pb(range(5)):
time.sleep(0.2)
```
Sample output (colors omitted in plain-text view):
```
INFO hello from logbar
INFO this line shows once
INFO [###---------------] 20% (1/5)
```
# Logging
The shared instance exposes the standard level helpers plus `once` variants:
```py
log.debug("details...")
log.warn("disk space is low")
log.error("cannot connect to database")
log.critical.once("fuse blown, shutting down")
```
Typical mixed-level output (Note: Markdown cannot display ANSI colors):
```
DEBUG model version=v2.9.1
WARN disk space is low (5%)
ERROR cannot connect to database
CRIT fuse blown, shutting down
```
# Progress Bars
Progress bars accept any iterable or integer total:
```py
for item in log.pb(tasks):
process(item)
for _ in log.pb(500).title("Downloading"):
time.sleep(0.05)
```
Manual mode gives full control when you need to interleave logging and redraws:
```py
pb = log.pb(jobs).title("Processing").manual()
for job in pb:
log.info(f"starting {job}")
pb.subtitle(f"in-flight: {job}").draw()
run(job)
log.info(f"finished {job}")
```
Progress bar snapshot (plain-text example):
```
INFO Processing [##########------------] 40% (8/20) in-flight: step-8
```
The bar always re-renders at the bottom, so log lines never overwrite your progress.
### Indeterminate Progress
When the total work is unknown, `log.spinner()` provides a rolling indicator that redraws every 500 ms until closed:
```py
with log.spinner("Loading model") as spinner:
load_weights()
spinner.subtitle("warming up")
warm_up()
```
The rolling bar animates automatically while attached. Close it explicitly with `spinner.close()` if you are not using the context manager.
### Multiple Progress Bars
LogBar keeps each progress bar on its own line and restacks them whenever they redraw. Later bars always appear closest to the live log output.
```py
pb_fetch = log.pb(range(80)).title("Fetch").manual()
pb_train = log.pb(range(120)).title("Train").manual()
for _ in pb_fetch:
pb_fetch.draw()
time.sleep(0.01)
for _ in pb_train:
pb_train.draw()
time.sleep(0.01)
pb_train.close()
pb_fetch.close()
```
Sample stacked output (plain-text view):
```
INFO Fetch [███████░░░░░░░░░░░░░░░░░░░░░░░░░░░░] | 58.8% 00:00:46 / 00:01:19
INFO Train [█████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░] | 37.5% 00:01:15 / 00:03:20
```
## Progress Bar Styling
Pick from bundled palettes or create your own blocks and colors:
```py
pb = log.pb(250)
pb.style('sunset') # bundled gradients: emerald_glow, sunset, ocean, matrix, mono
pb.fill('▓', empty='·') # override glyphs
pb.colors(fill=['#ff9500', '#ff2d55'], head='mint') # custom palette, optional head accent
pb.colors(empty='slate') # tint the empty track
pb.head('>', color='82') # custom head glyph + color index
```
`ProgressBar.available_styles()` lists builtin styles, and you can register additional ones with `ProgressBar.register_style(...)` or switch defaults globally via `ProgressBar.set_default_style(...)`. Custom colors accept ANSI escape codes, 256-color indexes (e.g. `'82'`), or hex strings (`'#4c1d95'`).
Styled output (plain-text view with ANSI removed):
```
INFO Upload [▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉···········] | 62.0% 00:01:48 / 00:02:52
```
# Columns (Table)
Use `log.columns(...)` to format aligned tables while logging data streams. Print the column header per context with `cols.info.header()` (or `cols.warn.header()`, etc.). Columns support spans and three width hints:
- character width: `"24"`
- percentage of the available log width: `"30%"`
- content-driven fit: `"fit"`
```py
cols = log.columns(
{"label": "tag", "width": "fit"},
{"label": "duration", "width": 8},
{"label": "message", "span": 2}
)
cols.info.header()
cols.info("startup", "1.2s", "ready", "subsystem online")
cols.info("alignment", "0.5s", "resizing", "fit width active")
```
Sample table output (plain-text):
```
INFO +----------+----------+-----------------------------+------------------------------+
INFO | tag | duration | message | message |
INFO +----------+----------+-----------------------------+------------------------------+
INFO | startup | 1.2s | ready | subsystem online |
INFO +----------+----------+-----------------------------+------------------------------+
INFO | alignment| 0.5s | resizing | fit width active |
INFO +----------+----------+-----------------------------+------------------------------+
```
Notice how the `tag` column expands precisely to the longest value thanks to `width="fit"`.
You can update column definitions at runtime:
```py
cols.update({
"message": {"width": "40%"},
"duration": {"label": "time"}
})
```
# Replacing `tqdm`
The API mirrors common `tqdm` patterns while staying more Pythonic:
```py
# tqdm
for n in tqdm.tqdm(range(1000)):
consume(n)
# logbar
for n in log.pb(range(1000)):
consume(n)
```
Manual update comparison:
```py
# tqdm manual mode
with tqdm.tqdm(total=len(items)) as pb:
for item in items:
handle(item)
pb.update()
# logbar manual redraw
with log.pb(items).manual() as pb:
for item in pb:
handle(item)
pb.render()
```
# Advanced Tips
- Combine columns and progress bars by logging summaries at key checkpoints.
- Use `log.warn.once(...)` to keep noisy health checks readable.
- For multi-line messages, pre-format text and pass it as a single string; LogBar keeps borders intact.
Raw data
{
"_id": null,
"home_page": null,
"name": "LogBar",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3",
"maintainer_email": null,
"keywords": "logger, logging, progressbar, progress bar, cli, terminal, lightweight, zero dependency, tqdm, tabulate",
"author": null,
"author_email": "ModelCloud <qubitium@modelcloud.ai>",
"download_url": "https://files.pythonhosted.org/packages/c0/1f/ece7d1031b84e219e2c815b8c8c0ca2fc59ae53d6b9a565c51c96721b3ac/logbar-0.1.7.tar.gz",
"platform": null,
"description": "<div align=center>\n\n<image src=\"https://github.com/user-attachments/assets/ce85bc38-6741-4a86-8ca9-71c13c7fc563\" width=50%>\n</image>\n <h1>LogBar</h1>\n\n A unified logger, table renderer, and progress bar utility with zero runtime dependencies.\n</div>\n\n<p align=\"center\" >\n <a href=\"https://github.com/ModelCloud/LogBar/releases\" style=\"text-decoration:none;\"><img alt=\"GitHub release\" src=\"https://img.shields.io/github/release/ModelCloud/LogBar.svg\"></a>\n <a href=\"https://pypi.org/project/logbar/\" style=\"text-decoration:none;\"><img alt=\"PyPI - Version\" src=\"https://img.shields.io/pypi/v/logbar\"></a>\n <a href=\"https://pepy.tech/projects/logbar\" style=\"text-decoration:none;\"><img src=\"https://static.pepy.tech/badge/logbar\" alt=\"PyPI Downloads\"></a>\n <a href=\"https://github.com/ModelCloud/LogBar/blob/main/LICENSE\"><img src=\"https://img.shields.io/pypi/l/logbar\" alt=\"License\"></a>\n <a href=\"https://huggingface.co/modelcloud/\"><img src=\"https://img.shields.io/badge/Hugging%20Face-ModelCloud-%23ff8811.svg\"></a>\n</p>\n\n\n# Features\n\n- Shared singleton logger with per-level colorized output.\n- `once` helpers prevent duplicate log spam automatically.\n- Stackable progress bars that stay anchored while your logs flow freely.\n- Built-in styling for progress bar fills, colors, gradients, and head glyphs.\n- Animated progress titles with a subtle sweeping highlight.\n- Column-aware table printer with spans, width hints, and `fit` sizing.\n- Zero dependencies; works anywhere Python runs.\n\n# Installation\n\n```bash\npip install logbar\n```\n\nLogBar works out-of-the-box with CPython 3.8+ on Linux, macOS, and Windows terminals.\n\n# Quick Start\n\n```py\nimport time\nfrom logbar import LogBar\n\nlog = LogBar.shared()\n\nlog.info(\"hello from logbar\")\nlog.info.once(\"this line shows once\")\nlog.info.once(\"this line shows once\") # silently skipped\n\nfor _ in log.pb(range(5)):\n time.sleep(0.2)\n```\n\nSample output (colors omitted in plain-text view):\n\n```\nINFO hello from logbar\nINFO this line shows once\nINFO [###---------------] 20% (1/5)\n```\n\n# Logging\n\nThe shared instance exposes the standard level helpers plus `once` variants:\n\n```py\nlog.debug(\"details...\")\nlog.warn(\"disk space is low\")\nlog.error(\"cannot connect to database\")\nlog.critical.once(\"fuse blown, shutting down\")\n```\n\nTypical mixed-level output (Note: Markdown cannot display ANSI colors):\n\n```\nDEBUG model version=v2.9.1\nWARN disk space is low (5%)\nERROR cannot connect to database\nCRIT fuse blown, shutting down\n```\n\n# Progress Bars\n\nProgress bars accept any iterable or integer total:\n\n```py\nfor item in log.pb(tasks):\n process(item)\n\nfor _ in log.pb(500).title(\"Downloading\"):\n time.sleep(0.05)\n```\n\nManual mode gives full control when you need to interleave logging and redraws:\n\n```py\npb = log.pb(jobs).title(\"Processing\").manual()\nfor job in pb:\n log.info(f\"starting {job}\")\n pb.subtitle(f\"in-flight: {job}\").draw()\n run(job)\n log.info(f\"finished {job}\")\n```\n\nProgress bar snapshot (plain-text example):\n\n```\nINFO Processing [##########------------] 40% (8/20) in-flight: step-8\n```\n\nThe bar always re-renders at the bottom, so log lines never overwrite your progress.\n\n### Indeterminate Progress\n\nWhen the total work is unknown, `log.spinner()` provides a rolling indicator that redraws every 500\u202fms until closed:\n\n```py\nwith log.spinner(\"Loading model\") as spinner:\n load_weights()\n spinner.subtitle(\"warming up\")\n warm_up()\n```\n\nThe rolling bar animates automatically while attached. Close it explicitly with `spinner.close()` if you are not using the context manager.\n\n### Multiple Progress Bars\n\nLogBar keeps each progress bar on its own line and restacks them whenever they redraw. Later bars always appear closest to the live log output.\n\n```py\npb_fetch = log.pb(range(80)).title(\"Fetch\").manual()\npb_train = log.pb(range(120)).title(\"Train\").manual()\n\nfor _ in pb_fetch:\n pb_fetch.draw()\n time.sleep(0.01)\n\nfor _ in pb_train:\n pb_train.draw()\n time.sleep(0.01)\n\npb_train.close()\npb_fetch.close()\n```\n\nSample stacked output (plain-text view):\n\n```\nINFO Fetch [\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591] | 58.8% 00:00:46 / 00:01:19\nINFO Train [\u2588\u2588\u2588\u2588\u2588\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591] | 37.5% 00:01:15 / 00:03:20\n```\n\n## Progress Bar Styling\n\nPick from bundled palettes or create your own blocks and colors:\n\n```py\npb = log.pb(250)\npb.style('sunset') # bundled gradients: emerald_glow, sunset, ocean, matrix, mono\npb.fill('\u2593', empty='\u00b7') # override glyphs\npb.colors(fill=['#ff9500', '#ff2d55'], head='mint') # custom palette, optional head accent\npb.colors(empty='slate') # tint the empty track\npb.head('>', color='82') # custom head glyph + color index\n```\n\n`ProgressBar.available_styles()` lists builtin styles, and you can register additional ones with `ProgressBar.register_style(...)` or switch defaults globally via `ProgressBar.set_default_style(...)`. Custom colors accept ANSI escape codes, 256-color indexes (e.g. `'82'`), or hex strings (`'#4c1d95'`).\n\nStyled output (plain-text view with ANSI removed):\n\n```\nINFO Upload [\u2589\u2589\u2589\u2589\u2589\u2589\u2589\u2589\u2589\u2589\u2589\u2589\u2589\u2589\u2589\u2589\u00b7\u00b7\u00b7\u00b7\u00b7\u00b7\u00b7\u00b7\u00b7\u00b7\u00b7] | 62.0% 00:01:48 / 00:02:52\n```\n\n# Columns (Table) \n\nUse `log.columns(...)` to format aligned tables while logging data streams. Print the column header per context with `cols.info.header()` (or `cols.warn.header()`, etc.). Columns support spans and three width hints:\n\n- character width: `\"24\"`\n- percentage of the available log width: `\"30%\"`\n- content-driven fit: `\"fit\"`\n\n```py\ncols = log.columns(\n {\"label\": \"tag\", \"width\": \"fit\"},\n {\"label\": \"duration\", \"width\": 8},\n {\"label\": \"message\", \"span\": 2}\n)\n\ncols.info.header()\ncols.info(\"startup\", \"1.2s\", \"ready\", \"subsystem online\")\ncols.info(\"alignment\", \"0.5s\", \"resizing\", \"fit width active\")\n```\n\nSample table output (plain-text):\n\n```\nINFO +----------+----------+-----------------------------+------------------------------+\nINFO | tag | duration | message | message |\nINFO +----------+----------+-----------------------------+------------------------------+\nINFO | startup | 1.2s | ready | subsystem online |\nINFO +----------+----------+-----------------------------+------------------------------+\nINFO | alignment| 0.5s | resizing | fit width active |\nINFO +----------+----------+-----------------------------+------------------------------+\n```\n\nNotice how the `tag` column expands precisely to the longest value thanks to `width=\"fit\"`.\n\nYou can update column definitions at runtime:\n\n```py\ncols.update({\n \"message\": {\"width\": \"40%\"},\n \"duration\": {\"label\": \"time\"}\n})\n```\n\n# Replacing `tqdm`\n\nThe API mirrors common `tqdm` patterns while staying more Pythonic:\n\n```py\n# tqdm\nfor n in tqdm.tqdm(range(1000)):\n consume(n)\n\n# logbar\nfor n in log.pb(range(1000)):\n consume(n)\n```\n\nManual update comparison:\n\n```py\n# tqdm manual mode\nwith tqdm.tqdm(total=len(items)) as pb:\n for item in items:\n handle(item)\n pb.update()\n\n# logbar manual redraw\nwith log.pb(items).manual() as pb:\n for item in pb:\n handle(item)\n pb.render()\n```\n\n# Advanced Tips\n\n- Combine columns and progress bars by logging summaries at key checkpoints.\n- Use `log.warn.once(...)` to keep noisy health checks readable.\n- For multi-line messages, pre-format text and pass it as a single string; LogBar keeps borders intact.\n",
"bugtrack_url": null,
"license": null,
"summary": "A unified Logger and ProgressBar util with zero dependencies.",
"version": "0.1.7",
"project_urls": {
"Homepage": "https://github.com/ModelCloud/LogBar"
},
"split_keywords": [
"logger",
" logging",
" progressbar",
" progress bar",
" cli",
" terminal",
" lightweight",
" zero dependency",
" tqdm",
" tabulate"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "c01fece7d1031b84e219e2c815b8c8c0ca2fc59ae53d6b9a565c51c96721b3ac",
"md5": "ac5f0643755ceb4ea1fe9e5148c9c96d",
"sha256": "1ce539d394df355964abce377527259ea995212d876e3526b42f2708c76e85e2"
},
"downloads": -1,
"filename": "logbar-0.1.7.tar.gz",
"has_sig": false,
"md5_digest": "ac5f0643755ceb4ea1fe9e5148c9c96d",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3",
"size": 34053,
"upload_time": "2025-10-23T13:17:48",
"upload_time_iso_8601": "2025-10-23T13:17:48.748341Z",
"url": "https://files.pythonhosted.org/packages/c0/1f/ece7d1031b84e219e2c815b8c8c0ca2fc59ae53d6b9a565c51c96721b3ac/logbar-0.1.7.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-10-23 13:17:48",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "ModelCloud",
"github_project": "LogBar",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "logbar"
}