Metadata-Version: 2.4
Name: mqdm
Version: 2.0.7
Summary: tqdm-compatible progress bars for loops, process/thread pools, async work, nested workers, and worker-safe logging
Author: Bea Steers
Maintainer: Bea Steers
License: MIT
Project-URL: Homepage, https://github.com/beasteers/mqdm
Project-URL: Documentation, https://beasteers.github.io/mqdm
Project-URL: Issues, https://github.com/beasteers/mqdm/issues
Keywords: progress,progress bars,tqdm alternative,parallel,concurrent,concurrent.futures progress,futures,multithreading,multiprocessing,process pool progress,thread pool progress,async progress,nested progress bars,worker-safe logging,non-interactive progress,pool,cross-process
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Programming Language :: Python :: 3.15
Classifier: Environment :: Console
Classifier: Topic :: Software Development :: Libraries
Classifier: Topic :: Utilities
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Requires-Dist: rich>=13
Provides-Extra: test
Requires-Dist: pytest; extra == "test"
Requires-Dist: fire; extra == "test"
Provides-Extra: dev
Requires-Dist: fire; extra == "dev"
Requires-Dist: ipython; extra == "dev"
Requires-Dist: pyinstrument; extra == "dev"
Requires-Dist: pdbr; extra == "dev"
Provides-Extra: docs
Requires-Dist: mkdocs; extra == "docs"
Requires-Dist: mkdocs-material; extra == "docs"
Requires-Dist: mkdocstrings[python]; extra == "docs"
Requires-Dist: pymdown-extensions; extra == "docs"
Requires-Dist: ruff; extra == "docs"

# mqdm

Pretty, worker-aware progress bars for Python loops, process/thread pools, async
work, nested workers, and non-interactive environments.

`mqdm` keeps a `tqdm`-like feel, but is designed to work seamlessly across
parallel workers. It is a good fit when progress needs to survive processes,
threads, nested work, or worker logging without tearing up the terminal.

## Install

```bash
pip install mqdm
```

## Quick look

```python
import time
import mqdm

for folder in mqdm.mqdm(["cats", "clouds", "notes"], desc="indexing"):
    for _ in mqdm.mqdm(range(5), desc=lambda _, i: f"{folder} · file {i + 1}"):
        time.sleep(0.05)
```

In parallel:
```python
import time
import mqdm

def do_work(folder):
    for _ in mqdm.mqdm(range(5), desc=lambda _, i: f"{folder} · file {i + 1}"):
        time.sleep(0.05)

def main():
    mqdm.pool(do_work, ["cats", "clouds", "notes"], desc="indexing", n_workers=3)
    
if __name__ == "__main__":
    main()
```

For CI, agents, and other non-interactive consumers, use stable line-oriented
output:

```bash
MQDM_OUTPUT=plain python worker.py
```

See the [AI and integration guide](https://beasteers.github.io/mqdm/ai/) for
the quickest way to choose between `mqdm`, `tqdm`, Rich, and raw executors.

Full docs can be found [here](https://beasteers.github.io/mqdm).

## Docs

Local preview:

```bash
pip install -e ".[docs]"
mkdocs serve
```

## Tests

```bash
pip install -e ".[test]"
pytest
```
Test across multiple Python versions:
```bash
for py in 3.10 3.11 3.12 3.13 3.14 3.15; do
  echo "=== Python $py ==="
  uv run --python $py pytest tests/ -q 2>&1 || break
done
```
