vocal_helper.credentials module
vocal_helper.credentials
Credential resolution for the paid cloud backends, and nothing else.
vocal-helper is local-first: the two local modes need no account, no key and no network. This module exists only so the two paid modes can find their keys, and it is written so that a missing key means the mode is unavailable, never that something silently degrades or silently bills.
Why a module of its own
Three properties are easier to guarantee in one small place than scattered across the cloud stages.
Opt-in is structural.
credential()returns""when nothing is configured. Every cloud stage raises on an empty key rather than guessing, so there is no code path where a key arriving by accident turns a free run into a billed one.One resolution order, written down. Environment variable first (that is how continuous integration and one-off experiments inject a key), then the writable overlay, then
settings.yaml. The overlay wins over the file because the file is richly commented and meant to be read by humans, while the overlay is machine-written by a preferences panel; rewriting the commented file to store a secret would destroy its comments.Reporting without leaking.
credentials_status()answers “which paid services could run?” with booleans only. A status endpoint, adoctorcommand or a log line can say configured / not configured without ever putting a key where it might be copied.
The names are the ones the rest of the suite already uses, so a machine configured for another project’s paid path is configured for this one too.
Resolution order
For a name GLADIA_API_KEY:
os.environ["GLADIA_API_KEY"](also tried lower-cased);the
credentials:section of thecredentials.yamloverlay;the
credentials:section ofsettings.yaml.
Both files carry the same shape — a credentials: section of indented
NAME: value pairs — so one parser reads both and there is no second format to
learn or to keep in sync. They sit next to the working directory or at the
package’s repository root, exactly where
vocal_helper._settings.settings_path() already looks, and neither may be
committed.
Usage example
>>> import os
>>> os.environ["GLADIA_API_KEY"] = "k-123"
>>> credential("GLADIA_API_KEY")
'k-123'
>>> credential("NOT_CONFIGURED_ANYWHERE")
''
>>> del os.environ["GLADIA_API_KEY"]
- vocal_helper.credentials.credential(name, default='')[source]
Resolve one credential, environment first.
- Parameters:
- Returns:
The value, or
default. NeverNone, so a caller can test it with a plain truth check.- Return type:
Examples
>>> import os >>> os.environ["PYANNOTEAI_API_KEY"] = "p-456" >>> credential("PYANNOTEAI_API_KEY") 'p-456' >>> del os.environ["PYANNOTEAI_API_KEY"] >>> credential("PYANNOTEAI_API_KEY", default="absent") 'absent'
- vocal_helper.credentials.credentials_status()[source]
Report which paid services are configured, without revealing any value.
- Returns:
One entry per name in
PAID_SERVICES, plus one per service that isTrueonly when every key that service needs is present. A service with a single missing key reads as unavailable, which is the honest answer: the paid offline mode cannot run on half its providers.- Return type:
Examples
>>> status = credentials_status() >>> set(status) >= {"cloud_offline", "GLADIA_API_KEY"} True >>> all(isinstance(v, bool) for v in status.values()) True
- vocal_helper.credentials.overlay_path()[source]
Locate the writable
credentials.yamloverlay.The overlay is where a preferences panel persists keys a user typed, so the commented
settings.yamlis never rewritten. It carries the samecredentials:section shape assettings.yaml. Looked up in the current working directory first, then beside the package’s repository root.- Returns:
The overlay path. It may not exist yet;
set_credentials()creates it.- Return type:
Examples
>>> overlay_path().name 'credentials.yaml'
- vocal_helper.credentials.set_credentials(mapping)[source]
Persist
NAME: valuepairs into the writable overlay.Merges into any existing overlay, so a partial save keeps untouched keys, and skips empty values so a user interface can send masked placeholders back without wiping a stored key. Never touches
settings.yaml.- Parameters:
mapping (dict of str) – The pairs to store, e.g.
{"GLADIA_API_KEY": "..."}. Empty or whitespace-only values are ignored.- Returns:
The overlay path written.
- Return type:
Examples
>>> import tempfile, os, pathlib >>> d = tempfile.mkdtemp(); cwd = os.getcwd(); os.chdir(d) >>> _ = pathlib.Path("credentials.yaml").write_text("") >>> p = set_credentials({"GLADIA_API_KEY": "written", "BLANK_KEY": " "}) >>> "GLADIA_API_KEY: written" in p.read_text() True >>> "BLANK_KEY" in p.read_text() False >>> credential("GLADIA_API_KEY") 'written' >>> os.chdir(cwd)