audio / deepgram /options.py
rehanaliraza
app
d5b44da
Raw
History Blame Contribute Delete
9.28 kB
# Copyright 2023-2024 Deepgram SDK contributors. All Rights Reserved.
# Use of this source code is governed by a MIT license that can be found in the LICENSE file.
# SPDX-License-Identifier: MIT
import sys
import re
import os
from typing import Dict, Optional
import logging
import numbers
from deepgram import __version__
from .utils import verboselogs
from .errors import DeepgramApiKeyError
class DeepgramClientOptions: # pylint: disable=too-many-instance-attributes
"""
Represents options for configuring a Deepgram client.
This class allows you to customize various options for interacting with the Deepgram API.
Attributes:
api_key: (Optional) A Deepgram API key used for authentication. Default uses the `DEEPGRAM_API_KEY` environment variable.
url: (Optional) The URL used to interact with production, On-prem, and other Deepgram environments. Defaults to `api.deepgram.com`.
verbose: (Optional) The logging level for the client. Defaults to `verboselogs.WARNING`.
headers: (Optional) Headers for initializing the client.
options: (Optional) Additional options for initializing the client.
"""
_logger: verboselogs.VerboseLogger
_inspect_listen: bool = False
_inspect_speak: bool = False
def __init__(
self,
api_key: str = "",
url: str = "",
verbose: int = verboselogs.WARNING,
headers: Optional[Dict] = None,
options: Optional[Dict] = None,
): # pylint: disable=too-many-positional-arguments
self._logger = verboselogs.VerboseLogger(__name__)
self._logger.addHandler(logging.StreamHandler())
if api_key is None:
api_key = ""
self.verbose = verbose
self.api_key = api_key
if headers is None:
headers = {}
self._update_headers(headers=headers)
if len(url) == 0:
url = "api.deepgram.com"
self.url = self._get_url(url)
if options is None:
options = {}
self.options = options
if self.is_auto_flush_reply_enabled():
self._inspect_listen = True
if self.is_auto_flush_speak_enabled():
self._inspect_speak = True
def set_apikey(self, api_key: str):
"""
set_apikey: Sets the API key for the client.
Args:
api_key: The Deepgram API key used for authentication.
"""
self.api_key = api_key
self._update_headers()
def _get_url(self, url) -> str:
if not re.match(r"^https?://", url, re.IGNORECASE):
url = "https://" + url
return url.strip("/")
def _update_headers(self, headers: Optional[Dict] = None):
self.headers = {}
self.headers["Accept"] = "application/json"
if self.api_key:
self.headers["Authorization"] = f"Token {self.api_key}"
elif "Authorization" in self.headers:
del self.headers["Authorization"]
self.headers[
"User-Agent"
] = f"@deepgram/sdk/{__version__} python/{sys.version_info[1]}.{sys.version_info[2]}"
# Overwrite / add any headers that were passed in
if headers:
self.headers.update(headers)
def is_keep_alive_enabled(self) -> bool:
"""
is_keep_alive_enabled: Returns True if the client is configured to keep the connection alive.
"""
return self.options.get("keepalive", False) or self.options.get(
"keep_alive", False
)
def is_auto_flush_reply_enabled(self) -> bool:
"""
is_auto_flush_reply_enabled: Returns True if the client is configured to auto-flush for listen.
"""
auto_flush_reply_delta = float(self.options.get("auto_flush_reply_delta", 0))
return (
isinstance(auto_flush_reply_delta, numbers.Number)
and auto_flush_reply_delta > 0
)
def is_auto_flush_speak_enabled(self) -> bool:
"""
is_auto_flush_speak_enabled: Returns True if the client is configured to auto-flush for speak.
"""
auto_flush_speak_delta = float(self.options.get("auto_flush_speak_delta", 0))
return (
isinstance(auto_flush_speak_delta, numbers.Number)
and auto_flush_speak_delta > 0
)
def is_inspecting_listen(self) -> bool:
"""
is_inspecting_listen: Returns True if the client is inspecting listen messages.
"""
return self._inspect_listen
def is_inspecting_speak(self) -> bool:
"""
is_inspecting_speak: Returns True if the client is inspecting speak messages.
"""
return self._inspect_speak
class ClientOptionsFromEnv(
DeepgramClientOptions
): # pylint: disable=too-many-branches, too-many-statements
"""
This class extends DeepgramClientOptions and will attempt to use environment variables first before defaults.
"""
_logger: verboselogs.VerboseLogger
def __init__(
self,
api_key: str = "",
url: str = "",
verbose: int = verboselogs.WARNING,
headers: Optional[Dict] = None,
options: Optional[Dict] = None,
): # pylint: disable=too-many-positional-arguments
self._logger = verboselogs.VerboseLogger(__name__)
self._logger.addHandler(logging.StreamHandler())
self._logger.setLevel(verboselogs.WARNING) # temporary set for setup
if api_key is None:
api_key = ""
if api_key == "":
api_key = os.getenv("DEEPGRAM_API_KEY", "")
if api_key == "":
self._logger.critical("Deepgram API KEY is not set")
raise DeepgramApiKeyError("Deepgram API KEY is not set")
if url == "":
url = os.getenv("DEEPGRAM_HOST", "api.deepgram.com")
self._logger.notice(f"Deepgram host is set to {url}")
if verbose == verboselogs.WARNING:
_loglevel = os.getenv("DEEPGRAM_LOGGING", "")
if _loglevel != "":
verbose = int(_loglevel)
if isinstance(verbose, str):
match verbose:
case "NOTSET":
self._logger.notice("Logging level is set to NOTSET")
verbose = verboselogs.NOTSET
case "SPAM":
self._logger.notice("Logging level is set to SPAM")
verbose = verboselogs.SPAM
case "DEBUG":
self._logger.notice("Logging level is set to DEBUG")
verbose = verboselogs.DEBUG
case "VERBOSE":
self._logger.notice("Logging level is set to VERBOSE")
verbose = verboselogs.VERBOSE
case "NOTICE":
self._logger.notice("Logging level is set to NOTICE")
verbose = verboselogs.NOTICE
case "WARNING":
self._logger.notice("Logging level is set to WARNING")
verbose = verboselogs.WARNING
case "SUCCESS":
self._logger.notice("Logging level is set to SUCCESS")
verbose = verboselogs.SUCCESS
case "ERROR":
self._logger.notice("Logging level is set to ERROR")
verbose = verboselogs.ERROR
case "CRITICAL":
self._logger.notice("Logging level is set to CRITICAL")
verbose = verboselogs.CRITICAL
case _:
self._logger.notice("Logging level is set to WARNING")
verbose = verboselogs.WARNING
self._logger.notice(f"Logging level is set to {verbose}")
if headers is None:
headers = {}
for x in range(0, 20):
header = os.getenv(f"DEEPGRAM_HEADER_{x}", None)
if header is not None:
headers[header] = os.getenv(f"DEEPGRAM_HEADER_VALUE_{x}", None)
self._logger.debug(
"Deepgram header %s is set with value %s",
header,
headers[header],
)
else:
break
if len(headers) == 0:
self._logger.notice("Deepgram headers are not set")
headers = None
if options is None:
options = {}
for x in range(0, 20):
param = os.getenv(f"DEEPGRAM_PARAM_{x}", None)
if param is not None:
options[param] = os.getenv(f"DEEPGRAM_PARAM_VALUE_{x}", None)
self._logger.debug(
"Deepgram option %s is set with value %s", param, options[param]
)
else:
break
if len(options) == 0:
self._logger.notice("Deepgram options are not set")
options = None
super().__init__(
api_key=api_key, url=url, verbose=verbose, headers=headers, options=options
)