Core APIs¶
The mqdm progress bar.
mqdm.mqdm
¶
mqdm(
it: Iterable[T] | int | str | None = None,
desc: str | DescFunc[T] | None = None,
*,
disable: bool | None = None,
runtime: Runtime | None = None,
task_id: TaskId | TaskState | None = None,
task_kw: dict[str, Any] | None = None,
completed: int = 0,
total: float | None = None,
start: bool = True,
visible: bool = True,
bytes: bool = False,
**fields: Any,
)
Bases: Generic[T]
Wrap an iterable or manual task with an mqdm progress bar.
The interface is intentionally close to tqdm while using Rich for
rendering and mqdm's runtime model for worker-safe output.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
it
|
Iterable[T] | int | str | None
|
Iterable to wrap. If an |
None
|
desc
|
str | DescFunc[T] | None
|
Static description or per-item description callback. |
None
|
runtime
|
Runtime | None
|
Runtime that should own this bar. Defaults to the current runtime. |
None
|
disable
|
bool | None
|
Whether rendering should be disabled while counters continue to update. |
None
|
task_id
|
TaskId | TaskState | None
|
Existing task identifier or detached task state to restore. |
None
|
task_kw
|
dict[str, Any] | None
|
Extra keyword arguments for the initial task creation. |
None
|
start
|
bool
|
Whether the task should start immediately. |
True
|
total
|
float | None
|
Optional total item count. |
None
|
completed
|
int
|
Initial completed count. |
0
|
visible
|
bool
|
Whether the task should be visible. |
True
|
bytes
|
bool
|
Whether to render byte-oriented columns. |
False
|
**fields
|
Any
|
Additional task fields forwarded to Rich. |
{}
|
Example
# wrap any iterable
for x in mqdm.mqdm(items, desc="processing"):
...
# an int is treated as range(n); a lone string is the description
for i in mqdm.mqdm(100):
...
# no iterable: a manual bar you drive yourself
with mqdm.mqdm(total=len(items), desc="processing") as bar:
for x in items:
...
bar.advance()
set
¶
set(**kw: Any) -> mqdm[T]
Change any field of the bar — count, label, total, visibility, or custom fields.
Every facet is a keyword, and you can change several at once:
completed=sets the counter to an absolute value;advance=moves it by a relative amount.total=rescales the bar mid-run.description=relabels it; pass a callabledesc=lambda item, i: ...once and it is reused on every step.visible=hides or shows the bar;leave=/transient=control whether the row stays on screen after it finishes.- any other keyword becomes a custom task field, for use with custom columns.
For a plain increment in a hot loop, prefer :meth:advance.
Example
bar = mqdm.mqdm(total=100, desc="downloading")
bar.set(completed=40, description="downloading · 40%") # count + label together
bar.set(total=160) # grew mid-run
bar.set(description="verifying", completed=0, total=3) # re-scope for a new phase
advance
¶
advance(n: int = 1, arg: Any = ...) -> mqdm[T]
Fast increment for tight loops — the way to step a bar by hand.
Only moves the counter, and batches redraws to the refresh rate, so it
sustains millions of steps per second (~10-20x faster than :meth:update).
Pass arg= to also refresh a dynamic desc=lambda item, i: ... on the
same cheap path.
Because updates are batched, bar.n can lag by up to a frame until the
next flush (reconciled when the bar closes). Use :meth:set / :meth:update
when you need to change something other than the count, or need an exact
bar.n right now.
Note
Iterating with for x in mqdm(...) already advances for you — reach
for this only in a manual loop.
Example
with mqdm.mqdm(total=len(rows)) as bar:
for row in rows:
process(row)
bar.advance()
update
¶
update(advance: int = 1, **kw: Any) -> mqdm[T]
Increment the counter by advance — a convenience for set(advance=...).
Applies immediately and accepts any other :meth:set field alongside the
step. In a tight loop where you only move the counter, :meth:advance is
~10-20x faster.
Example
with mqdm.mqdm(total=len(chunks)) as bar:
for chunk in chunks:
bar.update(len(chunk), description=f"read {chunk.name}")
__enter__
¶
__enter__() -> mqdm[T]
Open the bar as a context manager, attaching it to the live display.
Example
with mqdm.mqdm(total=len(items), desc="processing") as bar:
for x in items:
...
bar.advance()
open
¶
open() -> mqdm[T]
Attach the bar to the live display; reverses :meth:close.
A bar is already attached when created and by with / iteration, so this
is mainly for reattaching one you detached with :meth:close.
Example
bar.close() # detach, keeping its state
... # other terminal work
bar.open() # bring it back where it left off
close
¶
close(remove: bool | None = None) -> mqdm[T]
Detach the bar from the live display, preserving its task state.
remove controls whether the row is erased: None (default) removes it
only if the bar is transient; True / False force it either way. A
closed bar can be reopened later with :meth:open.
Example
bar = mqdm.mqdm(total=len(steps), desc="processing")
for step in steps:
run(step)
bar.advance()
bar.close(remove=True) # detach and erase the finished row
__call__
¶
__call__(
iter: Iterable[T] | AsyncIterable[T] | int | str | None,
desc: str | DescFunc[T] | None = None,
total: float | None = None,
**kw: Any,
) -> mqdm[T]
Bind (or rebind) the bar to an iterable and start counting.
This backs mqdm(it, ...) and bar(it); iterating the result advances
the bar for you. An int is treated as range(it) and a str as the
description (when desc is omitted); total defaults to len(it) when
the length is known. Passing None (no iterable) just applies the given
fields, like :meth:set. Both sync and async iterables work — use
async for for the latter.
Example
# open the bar first, then bind the iterable to it
with mqdm.mqdm(desc="processing") as pbar:
for x in pbar(items):
...
__iter__
¶
__iter__() -> Iterator[T]
Iterate the bound iterable, advancing the bar per item (for x in bar).
The bar must be bound to a sync iterable (via mqdm(it) or bar(it));
iterating one bound to an async iterable raises — use async for instead.
Example
for x in mqdm.mqdm(items, desc="processing"):
...
__aiter__
¶
__aiter__() -> AsyncIterator[T]
Async-iterate the bound async iterable, advancing per item (async for x in bar).
The bar must be bound to an async iterable; using async for on a
sync-bound bar raises — use a plain for instead.
Example
async for x in mqdm.mqdm(aiter_source(), desc="streaming"):
...