Summary
Six runtime dependencies are only imported by the bundled apps and tools, never by the
library itself. Installing bumble to use it as a Bluetooth stack currently also installs a
web server, a CLI framework, and a terminal UI toolkit.
Would you consider moving them behind an optional extra, e.g. bumble[apps]?
Detail
Checked against 0.0.233, counting files that import each module under bumble/ versus
apps/ + tools/:
| Dependency |
core |
apps/tools |
click |
0 |
24 |
aiohttp |
0 |
2 |
prompt_toolkit |
0 |
2 |
prettytable |
0 |
1 |
humanize |
0 |
1 |
tomli |
0 |
1 |
aiohttp is the one that prompted this. It is used only by apps/speaker/speaker.py and
apps/lea_unicast/app.py, both for aiohttp.web to serve a browser UI. We consume bumble
purely as a library (bumble.device, bumble.hci, bumble.gatt, bumble.transport, …) and
never import bumble.apps, but we still had to resolve a high-severity aiohttp advisory
(GHSA-cq5v-8q36-5273) in our lockfile because it is a transitive pin. Dependency scanners look
at the lockfile, not the call graph.
Why it matters
- Supply-chain surface: a BLE library pulls in an HTTP server and its dependency tree.
- Security churn: advisories in app-only packages become work for every downstream consumer.
- Install weight for embedded/CI environments that only need the stack.
Suggested shape
The project already uses optional dependencies for android and auracast, so this would
follow the existing pattern:
[project.optional-dependencies]
apps = [
"aiohttp ~= 3.8; platform_system!='Emscripten'",
"click >= 8.1.3; platform_system!='Emscripten'",
"prompt_toolkit >= 3.0.16; platform_system!='Emscripten'",
"prettytable >= 3.6.0; platform_system!='Emscripten'",
"humanize >= 4.6.0; platform_system!='Emscripten'",
"tomli ~= 2.2.1; platform_system!='Emscripten' and python_version<'3.11'",
]
all = ["bumble[android]", "bumble[auracast]", "bumble[apps]"]
pip install bumble gets the stack; pip install bumble[apps] gets the demos and CLI tools.
The obvious objection
[project.scripts] declares ~20 console scripts pointing at bumble.apps.*, so a bare
install would still create the entry points but they would fail on import. Options, roughly in
order of effort:
1. Document it, and let the ImportError speak for itself.
2. Have the app entry points catch ImportError and print "install bumble[apps] to use this tool".
3. Move the scripts under the extra too, if the packaging tooling allows it cleanly.
Happy to send a PR for whichever shape you prefer, if this is something you would take.
Summary
Six runtime dependencies are only imported by the bundled apps and tools, never by the
library itself. Installing
bumbleto use it as a Bluetooth stack currently also installs aweb server, a CLI framework, and a terminal UI toolkit.
Would you consider moving them behind an optional extra, e.g.
bumble[apps]?Detail
Checked against 0.0.233, counting files that import each module under
bumble/versusapps/+tools/:clickaiohttpprompt_toolkitprettytablehumanizetomliaiohttpis the one that prompted this. It is used only byapps/speaker/speaker.pyandapps/lea_unicast/app.py, both foraiohttp.webto serve a browser UI. We consume bumblepurely as a library (
bumble.device,bumble.hci,bumble.gatt,bumble.transport, …) andnever import
bumble.apps, but we still had to resolve a high-severityaiohttpadvisory(GHSA-cq5v-8q36-5273) in our lockfile because it is a transitive pin. Dependency scanners look
at the lockfile, not the call graph.
Why it matters
Suggested shape
The project already uses optional dependencies for
androidandauracast, so this wouldfollow the existing pattern: