Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion deepgram/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
import logging, verboselogs
import os

from .clients.live.client import LiveOptions
from .clients.prerecorded.client import PrerecordedOptions
from .clients.listen import ListenClient, PreRecordedClient
from .clients.manage.client import ManageClient
from .clients.onprem.client import OnPremClient
Expand Down Expand Up @@ -34,14 +36,18 @@ class DeepgramClient:
onprem: Returns an OnPremClient instance for interacting with Deepgram's on-premises API.
"""

def __init__(self, api_key: str, config: Optional[DeepgramClientOptions] = None):
def __init__(
self, api_key: str = "", config: Optional[DeepgramClientOptions] = None
):
verboselogs.install()
self.logger = logging.getLogger(__name__)
self.logger.addHandler(logging.StreamHandler())

if not api_key:
# Default to `None` for on-prem instances where an API key is not required
api_key = os.getenv("DEEPGRAM_API_KEY", None)
if not api_key:
self.logger.warning("WARNING: API key is missing")

self.api_key = api_key
if config is None: # Use default configuration
Expand Down
24 changes: 14 additions & 10 deletions deepgram/clients/live/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,25 @@
# SPDX-License-Identifier: MIT

from urllib.parse import urlparse, urlunparse, parse_qs, urlencode
from typing import Dict

from .errors import DeepgramError

def append_query_params(url, params=""):

def append_query_params(url, params):
parsed_url = urlparse(url)
query_params = parse_qs(parsed_url.query)

if params:
for key, value in params.items():
if isinstance(value, bool):
value = str(value).lower()
if isinstance(value, list):
for item in value:
query_params[key] = query_params.get(key, []) + [str(item)]
else:
query_params[key] = [str(value)]
for key, value in params.items():
if value is None:
continue
if isinstance(value, bool):
value = str(value).lower()
if isinstance(value, list):
for item in value:
query_params[key] = query_params.get(key, []) + [str(item)]
else:
query_params[key] = [str(value)]

updated_query_string = urlencode(query_params, doseq=True)
updated_url = parsed_url._replace(query=updated_query_string).geturl()
Expand Down
3 changes: 3 additions & 0 deletions deepgram/clients/live/v1/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ def start(self, options: LiveOptions = None):
self.logger.info("options: %s", options)

self.options = options
if isinstance(options, LiveOptions):
self.logger.info("LiveOptions switching class -> json")
self.options = self.options.to_dict()

if self._socket is not None:
self.logger.error("socket is already initialized")
Expand Down
4 changes: 4 additions & 0 deletions deepgram/clients/live/v1/legacy_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ async def __call__(self, options: LiveOptions = None):
self.logger.info("options: %s", options)

self.options = options
if isinstance(options, LiveOptions):
self.logger.info("LiveOptions switching class -> json")
self.options = self.options.to_dict()

url_with_params = append_query_params(self.websocket_url, self.options)
try:
self._socket = await _socket_connect(url_with_params, self.config.headers)
Expand Down
54 changes: 31 additions & 23 deletions deepgram/clients/live/v1/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,36 @@
# Use of this source code is governed by a MIT license that can be found in the LICENSE file.
# SPDX-License-Identifier: MIT

from typing import List, TypedDict
from dataclasses import dataclass
from dataclasses_json import dataclass_json
from typing import List, Optional


class LiveOptions(TypedDict, total=False):
callback: str
channels: int
diarize: bool
encoding: str
endpointing: int
interim_results: bool
keywords: str
language: str
model: str
multichannel: bool
numerals: bool
punctuate: bool
profanity_filter: bool
redact: bool
replace: str
sample_rate: int
search: str
smart_format: bool
tag: list
tier: str
version: str
@dataclass_json
@dataclass
class LiveOptions:
callback: Optional[str] = None
channels: Optional[int] = None
diarize: Optional[bool] = None
encoding: Optional[str] = None
endpointing: Optional[str] = None
interim_results: Optional[bool] = None
keywords: Optional[str] = None
language: Optional[str] = None
model: Optional[str] = None
multichannel: Optional[bool] = None
numerals: Optional[bool] = None
punctuate: Optional[bool] = None
profanity_filter: Optional[bool] = None
redact: Optional[bool] = None
replace: Optional[str] = None
sample_rate: Optional[int] = None
search: Optional[str] = None
smart_format: Optional[bool] = None
tag: Optional[list] = None
tier: Optional[str] = None
version: Optional[str] = None

def __getitem__(self, key):
_dict = self.to_dict()
return _dict[key]
2 changes: 1 addition & 1 deletion deepgram/clients/manage/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# SPDX-License-Identifier: MIT

from .v1.client import ManageClient as ManageClientLatest
from .v1.response import (
from .v1.options import (
ProjectOptions as ProjectOptionsLatest,
KeyOptions as KeyOptionsLatest,
ScopeOptions as ScopeOptionsLatest,
Expand Down
2 changes: 1 addition & 1 deletion deepgram/clients/manage/v1/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
BalancesResponse,
Balance,
)
from .response import (
from .options import (
ProjectOptions,
KeyOptions,
ScopeOptions,
Expand Down
115 changes: 115 additions & 0 deletions deepgram/clients/manage/v1/options.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
# Copyright 2023 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

from dataclasses import dataclass
from dataclasses_json import dataclass_json
from datetime import datetime
from typing import TypedDict, List, Optional

# Input


@dataclass_json
@dataclass
class ProjectOptions:
name: Optional[str] = ""

def __getitem__(self, key):
_dict = self.to_dict()
return _dict[key]


@dataclass_json
@dataclass
class KeyOptions:
comment: Optional[str] = ""
time_to_live_in_seconds: Optional[int] = 0
expiration_date: Optional[str] = ""
scopes: Optional[List[str]] = None
tags: Optional[List[str]] = None

def __getitem__(self, key):
_dict = self.to_dict()
if _dict["scopes"] is not None:
_dict["scopes"] = [str(scopes) for scopes in _dict["scopes"]]
if _dict["tags"] is not None:
_dict["tags"] = [str(tags) for tags in _dict["tags"]]
return _dict[key]


@dataclass_json
@dataclass
class ScopeOptions:
scope: Optional[str] = ""

def __getitem__(self, key):
_dict = self.to_dict()
return _dict[key]


@dataclass_json
@dataclass
class InviteOptions:
email: Optional[str] = ""
scope: Optional[str] = ""

def __getitem__(self, key):
_dict = self.to_dict()
return _dict[key]


@dataclass_json
@dataclass
class UsageRequestOptions:
start: Optional[str] = ""
end: Optional[str] = ""
limit: Optional[int] = 0
status: Optional[str] = ""

def __getitem__(self, key):
_dict = self.to_dict()
return _dict[key]


@dataclass_json
@dataclass
class UsageSummaryOptions:
start: Optional[str] = ""
end: Optional[str] = ""
accessor: Optional[str] = ""
tag: Optional[str] = ""
method: Optional[str] = ""
model: Optional[str] = ""
multichannel: Optional[bool] = False
interim_results: Optional[bool] = False
punctuate: Optional[bool] = False
ner: Optional[bool] = False
utterances: Optional[bool] = False
replace: Optional[bool] = False
profanity_filter: Optional[bool] = False
keywords: Optional[bool] = False
detect_topics: Optional[bool] = False
diarize: Optional[bool] = False
search: Optional[bool] = False
redact: Optional[bool] = False
alternatives: Optional[bool] = False
numerals: Optional[bool] = False
smart_format: Optional[bool] = False

def __getitem__(self, key):
_dict = self.to_dict()
return _dict[key]


@dataclass_json
@dataclass
class UsageFieldsOptions:
start: Optional[str] = ""
end: Optional[str] = ""

def __getitem__(self, key):
_dict = self.to_dict()
if _dict["details"] is not None:
_dict["details"] = Details.from_dict(_dict["details"])
return _dict[key]
Loading