Skip to content

Loops

Basic usage of mqdm is to wrap a loop with a progress bar.

Simple sequential

import mqdm
import time


xs = ["apples", "pears", "plums", "figs"]

for fruit in xs:
    for n in mqdm.mqdm(range(40), desc=fruit):
        time.sleep(0.1)

Nested loops

import mqdm
import time


xs = ["apples", "pears", "plums", "figs"]

for fruit in mqdm.mqdm(xs, desc="fruits"):
    for n in mqdm.mqdm(range(40), desc=fruit, leave=False):
        time.sleep(0.1)

Dynamic descriptions

import mqdm
import time


items = ["apples", "pears", "plums", "figs", "bananas", "kiwis", 
         "mangos", "oranges", "blueberries", "raspberries"] * 10

for fruit in mqdm.mqdm(items, desc=lambda x, i: f"Processing item {i}: {x}"):
    time.sleep(0.4)

Wrapping Iterators

import mqdm
import time

for i in range(3):
    # If we can't infer the iterable length (e.g. a generator), 
    # the progress bar will display as indeterminate.
    data_generator = (n for n in range(40))
    for n in mqdm.mqdm(data_generator, desc=f'without total=', leave=False):
        time.sleep(0.1)

    # If you know the length or an approximate length, 
    # you can give it to mqdm via the `total` argument. 
    data_generator = (n for n in range(40))
    for n in mqdm.mqdm(data_generator, total=40, desc=f'with total=', leave=False):
        time.sleep(0.1)

Async iterators

mqdm can also wrap an AsyncIterable directly. Use async for when the source itself is asynchronous.

import asyncio
import mqdm


async def source():
    for i in range(50):
        await asyncio.sleep(0.01)
        yield i


async def main():
    async for i in mqdm.mqdm(source(), total=50, desc="streaming"):
        await asyncio.sleep(0.05)


asyncio.run(main())

This keeps the same loop shape as the sync API: the bar advances once per yielded item, and dynamic descriptions still work the same way.

Manual increment

import mqdm
import time


with mqdm.mqdm(desc="compressing", total=4) as bar:
    for name in ["a.zip", "b.zip", "c.zip", "d.zip"]:
        time.sleep(1)
        bar.set_description(f"compressing {name}")
        bar.advance()

Printing above the progress bars

Unfortunately, you have to print using mqdm.print(...) instead of the built-in print(...) to avoid bungling the progress bars.

Take this up with rich or use logging.

import time
import mqdm
from mqdm import print


for i in mqdm.mqdm(range(10), desc="announcing"):
    time.sleep(0.2)
    print(f"finished step {i + 1}")

Logging

import time
import mqdm


import logging

mqdm.install_logging()
log = logging.getLogger(__name__)
log.setLevel(logging.INFO)


for i in mqdm.mqdm(range(100), desc="logging"):
    if i % 10 == 0:
        log.info("hi how's it going? %s / %s", i + 1, 400)
    time.sleep(0.05)