Skip to content

Keep heavy imports off the GUI startup path - #981

Open
Josef-Haupt wants to merge 2 commits into
mainfrom
startup-time
Open

Keep heavy imports off the GUI startup path#981
Josef-Haupt wants to merge 2 commits into
mainfrom
startup-time

Conversation

@Josef-Haupt

@Josef-Haupt Josef-Haupt commented Aug 16, 2026

Copy link
Copy Markdown
Member

Summary

  • Startup: the search tab imported birdnet_analyzer.audio (scipy.signal, librosa) while building, and every species-list coordinates block rendered a plotly map figure that open_window's demo.load regenerates on page load anyway. Both are now lazy. GUI startup to server-up drops from ~6.2 s to ~4.5 s locally.
  • Regression guard: tests/gui/test_startup_imports.py imports all tab modules and builds the full Blocks in a subprocess, asserting tensorflow, scipy, librosa, plotly and sklearn stay unloaded.
  • gui.utils importable without pywebview: the webview import moves into the dialog functions and open_window; the _WINDOW annotation is a string under TYPE_CHECKING. The sys.modules["webview"] stubs in the tests are removed so CI exercises this. (Raised by Copilot on Download progress #984; deferred there as out of scope.)
  • AGENTS.md: three conventions — the three ways a persisted GUI control gets its value (build / user / preset-or-params load), the code-comment policy (default to none; only constraints, non-obvious whys, measured values), and the pywebview/plotly-free test environment.

Verification

  • All tests/gui pass with webview and plotly made unimportable (CI's gui-tests condition), no stubs.
  • Startup regression test verified to fail against a tree with the eager imports restored.

This PR was originally the combined "General cleanup" draft; the frozen-CLI, sensitivity and download-progress parts landed separately as #982, #983 and #984.

🤖 Generated with Claude Code

Copilot AI lite review requested due to automatic review settings August 16, 2026 17:30

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates BirdNET-Analyzer’s handling of “sensitivity” to reflect BirdNET 3.0 behavior (sigmoid applied inside the model), ensuring analyses and the GUI don’t crash or misrepresent an unused setting, while also guarding GUI startup against heavy imports.

Changes:

  • Add supports_sensitivity() / effective_sensitivity() and apply coercion to sigmoid_sensitivity in inference and analysis orchestration.
  • Disable/reset the GUI sensitivity slider when the selected model doesn’t support it; defer some imports to keep GUI startup light.
  • Add tests and documentation covering sensitivity behavior and GUI startup/import constraints.

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
tests/test_model_utils.py Adds unit tests for sensitivity support logic and inference coercion for BirdNET 3.0.
tests/gui/test_startup_imports.py New test to prevent heavy modules from being imported during GUI tab import/build.
tests/gui/test_settings.py Adds coverage for stdout/stderr diversion behavior in frozen builds.
docs/breaking-changes.rst Documents that sensitivity is ignored for BirdNET 3.0 and how to tune detections instead.
birdnet_analyzer/settings.py Refactors frozen stdout/stderr diversion decision into _divert_output_to_log().
birdnet_analyzer/model_utils.py Introduces sensitivity support/coercion helpers and applies them before inference session creation.
birdnet_analyzer/gui/utils.py Disables/enables sensitivity slider based on selected model and avoids initial map-plot creation.
birdnet_analyzer/gui/search.py Moves heavyweight imports into inner functions to reduce tab build/import cost.
birdnet_analyzer/cli.py Updates --sensitivity help text and fixes a typo.
birdnet_analyzer/analyze/core.py Ensures recorded/serialized analysis params reflect the effective sensitivity actually used.
AGENTS.md Adds contributor guidance about GUI state dependencies (build time, user edits, programmatic updates).

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +87 to +89
assert result.returncode == 0, result.stderr
loaded = json.loads(result.stdout.splitlines()[-1])

Josef-Haupt and others added 2 commits August 17, 2026 20:57
The search tab imported birdnet_analyzer.audio (scipy.signal, librosa) while
building, and every species-list coordinates block rendered a plotly map
figure that open_window's demo.load regenerates on page load anyway. Both
now happen lazily; GUI startup to server-up drops from ~6.2 s to ~4.5 s.

A test imports all tab modules and builds the full Blocks in a subprocess,
asserting tensorflow, scipy, librosa, plotly and sklearn stay unloaded.

AGENTS.md: two conventions - the three ways a persisted GUI control gets its
value (build, user, preset/params load) and the code-comment rule.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The webview import moves from module level into the dialog functions and
open_window, and the _WINDOW annotation becomes a string under TYPE_CHECKING.
CI's gui-tests extra has no pywebview, so tests that reach gui.utils had to
stub sys.modules["webview"] first; those stubs are removed so CI exercises
the guarantee. AGENTS.md updated: no plotly in that environment either.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@Josef-Haupt Josef-Haupt changed the title General cleanup Keep heavy imports off the GUI startup path Aug 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants