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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions