Repository navigation
OP#10281: Add the browser progressbar for long operations - #838
Merged
randy-seng merged 9 commits intoSep 21, 2026
Merged
Conversation
randy-seng
force-pushed
the
task/10281-show-progress-of-long-operations-in-the-web-ui
branch
from
September 7, 2026 20:46
43dd659 to
aca9ce5
Compare
randy-seng
force-pushed
the
task/10281-show-progress-of-long-operations-in-the-web-ui
branch
from
September 9, 2026 21:50
aca9ce5 to
1fe3737
Compare
randy-seng
force-pushed
the
task/10281-show-progress-of-long-operations-in-the-web-ui
branch
from
September 9, 2026 22:22
1fe3737 to
bf995c9
Compare
randy-seng
force-pushed
the
task/10281-show-progress-of-long-operations-in-the-web-ui
branch
from
September 14, 2026 13:50
bf995c9 to
268e006
Compare
randy-seng
force-pushed
the
task/10281-show-progress-of-long-operations-in-the-web-ui
branch
from
September 16, 2026 11:42
9da1afa to
0af04d3
Compare
randy-seng
force-pushed
the
task/10281-show-progress-of-long-operations-in-the-web-ui
branch
from
September 16, 2026 14:06
0af04d3 to
f6374c3
Compare
Base automatically changed from
task/10280-make-the-source-of-tracks-and-videos-interchangeable
to
main
September 16, 2026 16:34
… in cancellation tests
… in progress bar tests
…ge in progress bar tests
randy-seng
force-pushed
the
task/10281-show-progress-of-long-operations-in-the-web-ui
branch
from
September 16, 2026 16:34
f6374c3 to
1939274
Compare
schubsen
requested changes
Sep 18, 2026
schubsen
approved these changes
Sep 21, 2026
randy-seng
deleted the
task/10281-show-progress-of-long-operations-in-the-web-ui
branch
September 21, 2026 12:46
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this does
Long operations in the web UI showed nothing.OtAnalyticsNiceGuiApplicationStarterstill wiredTqdmBuilder, soprogress for loading tracks or running analysis wentwhat progress reporting exists goes to the console the browser user never sees. This branch addsNiceguiProgressbar, a persistent dialog showing item counts, a determinate bar, the last completed item, and a cancel button, and pointsprogressbar_builderatNiceguiProgressbarBuilder. The CLI keeps tqdm.Why
Progress belongs to the application layer, the widget to the UI, so the state is split:
ProgressStateinOTAnalytics/application/progress.pyowns description, fraction, message, andfinished, driven by the existingCounterabstraction;NiceguiProgressbaronly renders it. Driving the bar byCounterrather than by iteration position matters because completions from concurrent work do not arrive in sequence order — hencecomplete(item)alongside the iterator path in__call__.Cancellationis deliberately a plain flag, notasyncio.Task.cancel(). The work being cancelled is a synchronous loop over a sequence — parsing tracks, calculating events — which never yields control while it runs. There is no moment at which something from outside could interrupt it, so the only way to stop it is for the loop itself to check a flag between items. Making that work asynchronous purely to gain an interruption point would mean reshaping the operations themselves, which is far more than showing a progressbar is worth. Theasyncio.Eventinside is for the other side: it lets the UI await cancellation instead of polling for it.Notes for the reviewer
Start with
NiceguiProgressbar.open()inplugin_ui/nicegui_gui/nicegui/progressbar.py:74. Two early returns carry real behaviour rather than defensiveness:context.client.is_auto_index_client— during--configpreload at startup there is no browser client, and building a dialog then raises. Progress is still tracked; only the rendering is skipped.self._state.finished— an empty operation would otherwise open a dialog nothing can ever close, because only a progress update reaches_refreshand closes it._refreshclosing the dialog onfinishedis the only close path besides cancel; if a caller reports fewer completions thantotal, the dialog stays open. That is thepersistentprop's cost and the reason the cancel button exists.NiceguiProgressbarBuilder.progressbarexposing the most recent bar is a seam for the concurrent-loading work, not used yet.Risk and rollout
Nothing outside the NiceGUI starter changes;
plugin_progress.tqdm_progressbar.TqdmBuilderis untouched and still used by the CLI (guarded by a new test).Worst case in the browser is a dialog that stays open after work finishes — visible immediately, and revertible by restoring the single line inSince nothing builds a progressbar yet, browser behaviour is unchanged by this PR; the dialog-stays-open risk becomes real with #840 and is revertible by restoring the single line innicegui_application.py:241.nicegui_application.py:241.Cancellationhas no consumer in this branch beyond the cancel button setting it; pressing cancel closes the dialog but does not yet stop the running operation.Testing
uv run pyteston the four new/changed test modules: 27 passed. Covers counts and current item, cancel setting the signal, auto-close at completion, the builder's iterator path, empty sequences, replacing a previous bar, and both no-browser cases.Still to verify by hand: an actual track load in the browser— a track load shows nothing on this branch, so that check belongs on #840. Worth verifying here: that--configpreload startup is unaffected.Follow-ups
#840 (OP#10282) wires the progressbar into
LoadTrackFilesand moves parsing off the event loop.Wire
Cancellationinto the operations themselves so cancel aborts the work, not just the dialog.OP#10281