From b15bbb6f4bde79b5cdf4799b3a57c85eb9b9de6b Mon Sep 17 00:00:00 2001 From: Chuck Date: Tue, 7 Apr 2026 16:07:16 -0400 Subject: [PATCH] docs(requirements): document optional dependencies (scipy, psutil, Flask-Limiter) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A doc-vs-code crosscheck of every Python import in src/ and web_interface/ against requirements.txt found 3 packages that the code uses but requirements.txt doesn't list. Verified with grep that all 3 are wrapped in try/except blocks with documented fallback paths, so they're optional features rather than missing required deps: - scipy src/common/scroll_helper.py:26 → from scipy.ndimage import shift; HAS_SCIPY flag. Used for sub-pixel interpolation in scrolling. Falls back to a simpler shift algorithm without it. - psutil src/plugin_system/resource_monitor.py:15 → import psutil; PSUTIL_AVAILABLE flag. Used for per-plugin CPU/memory monitoring. Silently no-ops without it. - flask-limiter web_interface/app.py:42-43 → from flask_limiter import Limiter; wrapped at the caller. Used for accidental-abuse rate limiting on the web interface (not security). Web interface starts without rate limiting when missing. These were latent in two ways: 1. A user reading requirements.txt thinks they have the full feature set after `pip install -r requirements.txt`, but they don't get smoother scrolling, plugin resource monitoring, or rate limiting. 2. A contributor who deletes one of the packages from their dev env wouldn't know which feature they just lost — the fallbacks are silent. Added an "Optional dependencies" section at the bottom of requirements.txt with the version constraint, the file:line where each is used, the feature it enables, and the install command. The comment-only format means `pip install -r requirements.txt` still gives the minimal-feature install (preserving current behavior), while users who want the full feature set can copy the explicit pip install commands. Other findings from the same scan that came back as false positives or known issues: - web_interface_v2: dead pattern flagged in earlier iteration (still no real implementation; affects 11+ plugins via the same try/except dead-fallback pattern) - urllib3: comes with `requests` transitively - All 'src.', 'web_interface.', 'rgbmatrix', 'RGBMatrixEmulator' imports: internal modules - base_plugin / plugin_manager / store_manager / mocks / visual_display_manager: relative imports to local modules - freetype: false positive (freetype-py is in requirements.txt under the package name) Co-Authored-By: Claude Opus 4.6 (1M context) --- requirements.txt | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/requirements.txt b/requirements.txt index 80dc0d96..defec383 100644 --- a/requirements.txt +++ b/requirements.txt @@ -48,3 +48,25 @@ pytest>=7.4.0,<8.0.0 pytest-cov>=4.1.0,<5.0.0 pytest-mock>=3.11.0,<4.0.0 mypy>=1.5.0,<2.0.0 + +# ─────────────────────────────────────────────────────────────────────── +# Optional dependencies — the code imports these inside try/except +# blocks and gracefully degrades when missing. Install them for the +# full feature set, or skip them for a minimal install. +# ─────────────────────────────────────────────────────────────────────── +# +# scipy — sub-pixel interpolation in +# src/common/scroll_helper.py for smoother +# scrolling. Falls back to a simpler shift algorithm. +# pip install 'scipy>=1.10.0,<2.0.0' +# +# psutil — per-plugin resource monitoring in +# src/plugin_system/resource_monitor.py. The monitor +# silently no-ops when missing (PSUTIL_AVAILABLE = False). +# pip install 'psutil>=5.9.0,<6.0.0' +# +# Flask-Limiter — request rate limiting in web_interface/app.py +# (accidental-abuse protection, not security). The +# web interface starts without rate limiting when +# this is missing. +# pip install 'Flask-Limiter>=3.5.0,<4.0.0'