A device with no internet could not set itself up: the auto-install needed
PyPI. The rdm6300 and pyserial wheels now ship inside the package, so first
start works with no network at all.
Both wheels are pure Python (py3-none-any / py2.py3-none-any), which is what
makes this possible - the same files work on armv7l, aarch64 and x86_64. This
is the difference from the workstation app's Files/repository cache, which
held aarch64 manylinux binaries and so could not be committed; that cache only
ever existed on the Pi devices.
- bundled_wheel_dir() locates them; ensure_dependencies() prefers them
automatically, so the service needs no --wheel-dir.
- verify_wheels() checks SHA256SUMS before installing. A wheel that fails its
checksum is refused rather than installed, then PyPI is tried, and if that is
unreachable it reports exit 2 instead of proceeding unverified.
- local_wheel_missing() falls back to PyPI when the bundle does not cover a
requirement, instead of attempting a --no-index install that must fail.
- An explicit --wheel-dir that is incomplete or unverified is called out, not
silently swapped for PyPI.
Verified end to end: built wheel and sdist both contain the wheels; a venv
with no rdm6300 self-provisions with a dead proxy and no PIP_NO_INDEX; and a
tampered wheel is refused with nothing installed.
A freshly flashed device needed manual pip work before the reader would
start. It now checks its dependencies, installs whatever is missing, and
carries on.
- bootstrap.py: import check, pip invocation, and a re-check that does not
trust pip's exit code alone. Installs nothing when the libraries are
already present, so a normal start does no network work.
- --wheel-dir installs from local wheels with --no-index, for devices with
no internet. --no-install-deps opts out entirely.
- Outside a venv pip gets --break-system-packages, which Debian and
Raspberry Pi OS require before touching the system Python.
- reload_library() re-imports rdm6300 when it was installed at runtime, since
the module-level import already ran and failed.
- A failed install reports exit 2 and the exact manual command rather than
raising; stdout is flushed so the explanation is not printed after the
error when piped.