How Claude-Video Loads Whisper API Keys for Transcription: Environment and File-Based Discovery

Claude-Video uses the pure-stdlib load_api_key helper defined in skills/watch/scripts/whisper.py to discover API keys by checking environment variables first, then falling back to .env files in ~/.config/watch/ or the working directory, supporting both Groq and OpenAI backends.

The bradautomates/claude-video repository implements a dependency-free approach to loading Whisper API keys without requiring external configuration libraries. This mechanism prioritizes environment variables before scanning conventional dotenv locations, ensuring seamless integration across development and production environments. Understanding how Whisper API keys are loaded allows developers to configure transcription backends securely while maintaining zero external dependencies.

The load_api_key Implementation

The core logic resides in skills/watch/scripts/whisper.py within the load_api_key function (lines 98-112). This utility orchestrates key discovery through a prioritized search strategy that avoids external packages like python-dotenv.

Environment Variable Lookup

The helper first interrogates the current process environment via the internal _from_env function (lines 65-73). It searches for two specific variable names:

  • GROQ_API_KEY
  • OPENAI_API_KEY

The implementation uses os.environ.get() to retrieve values, sanitizing input by stripping whitespace to handle formatting inconsistencies:

def _from_env(name: str) -> str | None:
    value = os.environ.get(name)
    return value.strip() if value else None

Dotenv File Fallback

If environment variables are absent, the function falls back to file-based configuration via _from_dotenv (lines 74-91). The scanner checks two conventional paths in sequence:

  1. ~/.config/watch/.env (user-wide configuration directory)
  2. ./.env (repository working directory)

The parser reads each file line-by-line, ignoring comments and whitespace, extracting key values through pure Python string operations without external parsing libraries.

Backend Preference Logic

The load_api_key function accepts an optional preferred parameter to enforce a specific backend. According to lines 98-101:

  • If preferred="groq" or preferred="openai" is supplied, only that backend's key is retrieved
  • Without a preference, the function defaults to trying Groq first, then OpenAI

The function returns a tuple (backend, api_key) where backend identifies the provider. If no key is found anywhere, it returns (None, None) (lines 102-112).

Integration with the Transcription Workflow

The main entry point in skills/watch/scripts/watch.py invokes load_api_key conditionally—only when falling back to Whisper transcription (lines 39-48). This occurs when no subtitle files are available and the --no-whisper flag is not set.

The typical invocation passes the user's backend preference from command-line arguments:

backend, api_key = load_api_key(args.whisper)   # args.whisper may be "groq" or "openai"

When both values are returned successfully, they are passed to transcribe_video along with the video path and temporary audio file, selecting the appropriate endpoint for upload.

Configuration File Locations

Claude-Video searches for API keys using the following precedence:

  • Process environment: GROQ_API_KEY or OPENAI_API_KEY variables
  • User configuration: ~/.config/watch/.env
  • Local configuration: ./.env in the current working directory

The setup script at skills/watch/scripts/setup.py initializes the user-wide configuration by creating ~/.config/watch/.env when run.

Practical Usage Examples

Programmatic Key Retrieval

Import the loader directly for use in external scripts:

from skills.watch.scripts.whisper import load_api_key

# Prefer Groq if possible; otherwise fall back to OpenAI

backend, key = load_api_key()
if backend and key:
    print(f"Using {backend} backend with key {key[:4]}…")
else:
    print("No Whisper API key found – run the setup script.")

Explicit Backend Selection

Force a specific provider to bypass the default preference order:

backend, key = load_api_key(preferred="openai")   # forces OpenAI only

# Pass `backend` and `key` to transcribe_video(...)

Workflow Integration

The main script handles missing keys gracefully before attempting transcription:

if not transcript_segments and not args.no_whisper and video_path and meta.get("has_audio"):
    backend, api_key = load_api_key(args.whisper)   # may return (None, None)

    if backend and api_key:
        segments, used_backend = transcribe_video(
            video_path,
            work / "audio.mp3",
            backend=backend,
            api_key=api_key,
        )

Error Handling and User Guidance

When load_api_key returns (None, None), indicating no valid key was found in any location, watch.py outputs a diagnostic message (lines 55-64) directing users to execute the setup script. This creates the expected directory structure and template .env file at ~/.config/watch/.env, preventing silent failures and reducing configuration friction.

Summary

  • Environment-first discovery: Claude-Video checks GROQ_API_KEY and OPENAI_API_KEY environment variables before attempting file-based configuration
  • Dual fallback paths: The system scans ~/.config/watch/.env followed by ./.env when environment variables are unavailable
  • Backend-aware selection: The load_api_key function supports explicit backend preference or defaults to Groq-first, OpenAI-second ordering
  • Pure standard library: The implementation uses only os.environ and manual file parsing, avoiding external dependencies
  • Graceful degradation: Missing keys trigger user-friendly guidance toward the setup script rather than cryptic errors

Frequently Asked Questions

What environment variables does claude-video check for Whisper API keys?

Claude-Video searches for GROQ_API_KEY and OPENAI_API_KEY in the process environment. These variables correspond to the Groq and OpenAI Whisper endpoints respectively. The _from_env helper in skills/watch/scripts/whisper.py (lines 65-73) retrieves and sanitizes these values by stripping whitespace to ensure clean authentication headers.

How does claude-video handle missing API keys?

If load_api_key cannot locate a valid key in either environment variables or .env files, it returns the tuple (None, None). The calling code in watch.py detects this condition and prints a helpful message directing you to run the setup script located at skills/watch/scripts/setup.py. This script automatically creates the configuration directory and .env template at ~/.config/watch/.env.

Can I force claude-video to use a specific Whisper backend?

Yes. Pass the preferred parameter to load_api_key() with either "groq" or "openai" to restrict the search to only that provider's API key. When invoked from watch.py, this preference typically comes from command-line arguments (args.whisper). Without an explicit preference, the system defaults to checking Groq first, then OpenAI.

Where should I place my .env file for claude-video?

Claude-Video accepts .env files in two locations: ~/.config/watch/.env for user-wide configuration (recommended and created by the setup script), or ./.env in the current working directory for project-specific overrides. The system always checks environment variables first, then the user config, then the local directory, allowing you to layer configurations as needed.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →