fix(channels): inject embedded SDK into the sidecar --describe probe so the configure form isn't empty without pip install#6085
Merged
Conversation
The dashboard's Add-a-channel form is schema-driven off `python3 -m librefang.sidecar.adapters.<name> --describe`, probed once at boot by `routes/sidecar_describe.rs::describe_sidecar` and cached. That probe spawned the interpreter without the binary-embedded `librefang-sdk` on PYTHONPATH — unlike the live channel-spawn path in `librefang-channels::sidecar`, which has injected the embedded copy since the SDK was bundled. So on a fresh host with only `python3` and no `pip install librefang-sdk`, `--describe` failed with ModuleNotFoundError, and every adapter without a hand-maintained `static_fields` fallback (telegram, ntfy, gotify, mastodon, …) rendered a blank configure drawer — even though the adapter source ships embedded in the daemon binary. `describe_sidecar` now injects the embedded SDK exactly like the spawn path (`pythonpath_with_embedded`, exported `pub`), threading the kernel's authoritative `home_dir` through `populate_sidecar_schema_cache`. The probe now succeeds with just `python3` on PATH and the dashboard gets each adapter's authoritative live schema with zero setup; `static_fields` drops back to a true last resort (no usable `python3`, or the embedded extract errored). First-party adapter `--describe` is dependency-free (stdlib + the embedded `librefang.sidecar`; telegram talks to the Bot API over urllib), so no third-party install is needed to populate the form. Verified in the Linux dev container (python3 present, librefang-sdk NOT installed): `sidecar_describe_test` telegram/feishu probes now succeed and assert their real schema fields instead of skipping; check + clippy clean.
Four comment blocks added or modified by the sidecar-describe PR violated the "never write multi-line comment blocks — one short line max" and "never write multi-paragraph docstrings" rules in CLAUDE.md: - sidecar_describe.rs: 10-line // block explaining PYTHONPATH injection → 1 line - sidecar_describe.rs: 3rd doc-comment paragraph on describe_sidecar → merged as a single trailing sentence on paragraph 2 (no blank /// separator) - sidecar_describe_test.rs: 5-line // comment in telegram test → removed (the test name and code already make the intent clear) - server.rs: 7-line // block around populate_sidecar_schema_cache call (modified by the PR) → 1 line
The `static_fields` doc still said `--describe` fails / the form stays empty without `pip install librefang-sdk`. That stopped being true once `describe_sidecar` started injecting the embedded SDK: a `python3`-only host now gets the adapter's live schema, and `static_fields` is consulted only when the probe fails outright (no usable `python3`, or the embedded extract errored).
houko
enabled auto-merge (squash)
June 11, 2026 11:48
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.
Problem
Python sidecar adapters work zero-setup at runtime: the SDK (all adapter sources) is
include_dir!-bundled into the daemon binary, and the live spawn path injects it onto the child'sPYTHONPATHwhen the interpreter can't alreadyimport librefang.sidecar(librefang-channels::sidecar.rs→embedded_sdk::pythonpath_with_embedded). A fresh user needs onlypython3on PATH — nopip install.But the dashboard configure form never got the same treatment. The Add-a-channel form is schema-driven off
python3 -m librefang.sidecar.adapters.<name> --describe, probed at boot byroutes/sidecar_describe.rs::describe_sidecar— and that probe spawned the interpreter with a bareCommand::new, no embedded-SDK injection.Result on any host without
pip install librefang-sdk:--describefails withModuleNotFoundError: No module named 'librefang';static_fieldsfallback render an empty configure drawer — and that's telegram, ntfy, gotify, mastodon (channels.rscatalog:static_fields: None), i.e. the most common ones;Only feishu had a
static_fieldsfallback (which must be hand-synced with the PythonSCHEMAand drifts).Fix
describe_sidecarnow injects the embedded SDK exactly like the runtime spawn path, threading the kernel's authoritativehome_dir(KernelApi::home_dir(), never a recomputedLIBREFANG_HOME) throughpopulate_sidecar_schema_cache:librefang-channels: exportembedded_sdk::pythonpath_with_embedded(pub mod+pub fn); only that one function becomes crate-public.routes/sidecar_describe.rs:describe_sidecar(command, args, home_dir)injectsPYTHONPATHbefore spawning--describe. No-op when a real SDK install already wins (developer editable installs stay authoritative) or for non-Python commands.routes/channels.rs/server.rs: threadkernel.home_dir()to the boot probe.Now the probe succeeds with just
python3on PATH and the dashboard gets each adapter's authoritative live schema with zero setup.static_fieldsdrops back to a true last resort (no usablepython3, or the embedded extract errored).First-party adapter
--describeis dependency-free — stdlib + the embeddedlibrefang.sidecaronly; telegram talks to the Bot API overurllib, nopython-telegram-bot— so nothing third-party needs installing to populate the form.Verification (Linux dev container: python3 3.13 present,
librefang-sdkNOT installed)cargo test -p librefang-api --test sidecar_describe_test— 5/5 pass. The telegram and feishu probes now succeed and assert their real schema fields (TELEGRAM_BOT_TOKEN,FEISHU_APP_ID, …) instead of skipping with "SDK not installed" — direct end-to-end proof the embedded probe works without pip. The two-cfailure-mode tests still surface their errors (injection is a no-op for their assertions).cargo check -p librefang-channels -p librefang-api --lib— clean.cargo clippy -p librefang-channels -p librefang-api --lib -- -D warnings— clean.cargo fmt --check— clean.Scope
Independent of the goal-runner flake fix (#6083) and the Dependabot bump (#6080). The describe path is the only place that lacked the injection; the runtime spawn path already had it.