foley.sources.registry
Live-source adapter registry: auto-discovery + lazy loading (arioso’s registry, ported).
Scans foley.sources for sub-packages that declare a SOURCE_CONFIG
(a config.py with the plugin declaration), registers them, and lazily imports
+ instantiates each adapter only on first use. Mirrors arioso.registry /
PLATFORM_CONFIG (report 10 §4.1).
This is the live-source registry (Freesound; hosted generators in #6) — a
separate registry from the bulk-corpus
foley.sources.base.CORPUS_REGISTRY. The two adapter kinds have different
contracts (search / get / download vs iter_clips /
resolve_license) and different façades (foley.add_from() vs
foley.bootstrap()). They stay disjoint by construction: discovery only
picks up sub-packages (ispkg and not _-prefixed), so the flat bulk-corpus
modules (fsd50k.py …) and the flat helper modules here (base, http,
pull, registry) are never cross-captured.
Out-of-tree plugins — and test doubles — register directly via
register_source() (no package needed).
- foley.sources.registry.SOURCE_REGISTRY = {}
Public read alias of the registry (callers/tests inspect discovered sources).
- foley.sources.registry.discover_sources() list[str][source]
Scan
foley.sourcessub-packages for aSOURCE_CONFIGand register them.A valid live source is a sub-package of
foley.sources(ispkgand not_-prefixed) whoseconfig.pydefines aSOURCE_CONFIGdict with aname. Flat modules (bulk-corpus adapters + helpers) are skipped, so this never cross-captures the corpus adapters. Onlyconfig.pyis imported here (stdlib-cheap); the adapter loads lazily inget_source(). Idempotent — an already-registered name (e.g. a test double) is never overwritten.- Returns:
The list of discovered source names.
- foley.sources.registry.get_source(name: str) dict[source]
Return the
{'config', 'adapter'}entry forname, lazily building the adapter.Runs a discovery pass if
nameis not yet known, then instantiates the adapter on first use (cached in the entry).- Parameters:
name – The source name.
- Returns:
The registry entry (
{'config': dict, 'adapter': SourceAdapter, ...}).- Raises:
KeyError – If no such source is registered (after discovery).
- foley.sources.registry.list_sources(*, egress_allow: frozenset | None = None) list[str][source]
Return the names of registered live sources (runs discovery first).
- Parameters:
egress_allow – If given, keep only sources whose declared
config['data_egress']is in this set (the local-first / offline filter — seefoley.runtime.RuntimeConfig). A source that does not declaredata_egressis excluded (fail-closed).
- foley.sources.registry.local_sources() list[str][source]
The names of sources that run entirely on-device (
data_egress == 'local').
- foley.sources.registry.register_source(name: str, config: dict, adapter=None) None[source]
Register a live source directly (out-of-tree plugin or a test double).
Overwrites any existing entry for
name— the seam a test uses to inject a fake-transport-backed adapter. IfadapterisNoneit is lazily built fromconfigon firstget_source()(the source must then be an importablefoley.sources.<name>package).- Parameters:
name – The source name (the
add_from()/get_source()key).config – The
SOURCE_CONFIGdeclaration.adapter – An optional pre-instantiated adapter (bypasses lazy loading).