Skip to content

DeepgramClient() reads DEEPGRAM_API_KEY at import time, not at instantiation #734

Description

@samgutentag

Summary

api_key defaults to os.getenv("DEEPGRAM_API_KEY") directly in the __init__ signature, so Python evaluates it once, when the module is imported, not when the client is constructed. The idiomatic pattern (imports at the top of a file, load_dotenv() below them) therefore fails: the default is captured as None before the key is set, and DeepgramClient() raises even though DEEPGRAM_API_KEY is present by the time you instantiate.

Environment

  • deepgram-sdk 7.3.1
  • Python 3.14.6
  • macOS (Darwin 24.6.0)

Root cause

deepgram/base_client.py (Fern-generated), BaseClient.__init__:

api_key: typing.Optional[str] = os.getenv("DEEPGRAM_API_KEY"),   # evaluated at import
...
if api_key is None:
    raise ApiError(body="The client must be instantiated be either passing in api_key or setting DEEPGRAM_API_KEY")

os.getenv(...) as a default argument runs once, at function-definition (import) time, not per call.

Reproduction

import os
os.environ.pop("DEEPGRAM_API_KEY", None)         # not set in the shell at process start
from deepgram import DeepgramClient               # default captured as None HERE
os.environ["DEEPGRAM_API_KEY"] = "dummy-key"      # set afterward (what load_dotenv() does)
DeepgramClient()                                  # raises, despite the var being set

Output on 7.3.1:

set at instantiation: True
DeepgramClient() -> ApiError: ... The client must be instantiated be either passing in api_key or setting DEEPGRAM_API_KEY
DeepgramClient(api_key=...) -> constructed OK

Impact

The documented zero-config pattern (DeepgramClient() reading DEEPGRAM_API_KEY) only works if the variable is in the OS environment before the deepgram import runs. With python-dotenv (very common), load_dotenv() runs after the import, so the key is invisible. The error message ("set DEEPGRAM_API_KEY") is misleading because the variable is already set, which sends you to debug the wrong thing.

Suggested fix

Default the parameter to None and resolve the env var inside __init__ so it's read at call time:

def __init__(self, *, api_key: typing.Optional[str] = None, ...):
    if api_key is None:
        api_key = os.getenv("DEEPGRAM_API_KEY")
    if api_key is None:
        raise ApiError(body="The client must be instantiated by either passing in api_key or setting DEEPGRAM_API_KEY")

(Also worth fixing the grammar in the error string: "must be instantiated be either" -> "by either".) Since base_client.py is Fern-generated, the change belongs in the generator template.

Workaround

Pass the key explicitly, DeepgramClient(api_key=os.getenv("DEEPGRAM_API_KEY")), or call load_dotenv() before importing deepgram.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions