From e20766d743b4a148ca9951ac69264285248a30e6 Mon Sep 17 00:00:00 2001 From: David vonThenen <12752197+dvonthenen@users.noreply.github.com> Date: Wed, 25 Sep 2024 18:28:18 -0700 Subject: [PATCH] Fix Mismatch Structs on STT REST --- deepgram/__init__.py | 15 ++-- deepgram/audio/microphone/microphone.py | 5 +- deepgram/client.py | 9 ++- deepgram/clients/__init__.py | 9 ++- deepgram/clients/common/__init__.py | 6 -- deepgram/clients/common/v1/__init__.py | 3 - deepgram/clients/common/v1/shared_response.py | 64 ---------------- deepgram/clients/listen/__init__.py | 9 ++- deepgram/clients/listen/client.py | 19 +++-- deepgram/clients/listen/v1/__init__.py | 9 ++- deepgram/clients/listen/v1/rest/__init__.py | 6 +- deepgram/clients/listen/v1/rest/response.py | 46 ++++++++---- .../clients/listen/v1/websocket/__init__.py | 6 +- .../clients/listen/v1/websocket/response.py | 75 +++++++++++++++++-- 14 files changed, 157 insertions(+), 124 deletions(-) diff --git a/deepgram/__init__.py b/deepgram/__init__.py index a3286281..1d7568fe 100644 --- a/deepgram/__init__.py +++ b/deepgram/__init__.py @@ -61,11 +61,8 @@ ) from .client import ( ModelInfo, - Alternative, Hit, Search, - Channel, - Word, ) from .client import ( OpenResponse, @@ -92,6 +89,9 @@ # ErrorResponse, #### unique ListenWSMetadata, + ListenWSAlternative, + ListenWSChannel, + ListenWSWord, ) # prerecorded @@ -121,6 +121,8 @@ SyncPrerecordedResponse, #### shared # Average, + # Alternative, + # Channel, # Intent, # Intents, # IntentsInfo, @@ -132,9 +134,8 @@ # Topic, # Topics, # TopicsInfo, + # Word, #### unique - Alternative, - Channel, Entity, Hit, ListenRESTMetadata, @@ -150,7 +151,9 @@ Translation, Utterance, Warning, - Word, + ListenRESTAlternative, + ListenRESTChannel, + ListenRESTWord, ) # read diff --git a/deepgram/audio/microphone/microphone.py b/deepgram/audio/microphone/microphone.py index 15dd2a7b..ae452984 100644 --- a/deepgram/audio/microphone/microphone.py +++ b/deepgram/audio/microphone/microphone.py @@ -33,7 +33,7 @@ class Microphone: # pylint: disable=too-many-instance-attributes _is_muted: bool _asyncio_loop: asyncio.AbstractEventLoop - _asyncio_thread: threading.Thread + _asyncio_thread: Optional[threading.Thread] = None _exit: threading.Event _push_callback_org: Optional[Callable] = None @@ -142,6 +142,7 @@ def start(self) -> bool: ) else: self._logger.verbose("regular threaded callback") + self._asyncio_thread = None self._push_callback = self._push_callback_org self._stream = self._audio.open( @@ -267,7 +268,7 @@ def finish(self) -> bool: self._logger.notice("stopping asyncio loop...") self._asyncio_loop.call_soon_threadsafe(self._asyncio_loop.stop) self._asyncio_thread.join() - self._asyncio_thread = None # type: ignore + self._asyncio_thread = None self._logger.notice("_asyncio_thread joined") self._logger.notice("finish succeeded") diff --git a/deepgram/client.py b/deepgram/client.py index 673ad82a..08ef1717 100644 --- a/deepgram/client.py +++ b/deepgram/client.py @@ -37,11 +37,8 @@ ) from .clients import ( ModelInfo, - Alternative, Hit, Search, - Channel, - Word, ) from .clients import ( OpenResponse, @@ -86,6 +83,9 @@ # UnhandledResponse, #### unique ListenWSMetadata, + ListenWSAlternative, + ListenWSChannel, + ListenWSWord, ) # prerecorded @@ -154,6 +154,9 @@ Translation, Utterance, Warning, + ListenRESTAlternative, + ListenRESTChannel, + ListenRESTWord, ) # read diff --git a/deepgram/clients/__init__.py b/deepgram/clients/__init__.py index dcf0aaef..d490a9f4 100644 --- a/deepgram/clients/__init__.py +++ b/deepgram/clients/__init__.py @@ -31,11 +31,8 @@ # common (shared between listen rest and websocket) from .common import ( ModelInfo, - Alternative, Hit, Search, - Channel, - Word, ) from .common import ( OpenResponse, @@ -124,6 +121,9 @@ Translation, Utterance, Warning, + ListenRESTAlternative, + ListenRESTChannel, + ListenRESTWord, ) @@ -150,6 +150,9 @@ # UnhandledResponse, #### uniqye ListenWSMetadata, + ListenWSWord, + ListenWSAlternative, + ListenWSChannel, ) ## clients diff --git a/deepgram/clients/common/__init__.py b/deepgram/clients/common/__init__.py index 2018b362..1ecd39d0 100644 --- a/deepgram/clients/common/__init__.py +++ b/deepgram/clients/common/__init__.py @@ -16,11 +16,8 @@ from .v1 import ( BaseResponse as BaseResponseLatest, ModelInfo as ModelInfoLatest, - Word as WordLatest, - Alternative as AlternativeLatest, Hit as HitLatest, Search as SearchLatest, - Channel as ChannelLatest, ) # rest @@ -56,11 +53,8 @@ BaseResponse = BaseResponseLatest ModelInfo = ModelInfoLatest -Word = WordLatest -Alternative = AlternativeLatest Hit = HitLatest Search = SearchLatest -Channel = ChannelLatest Average = AverageLatest Intent = IntentLatest diff --git a/deepgram/clients/common/v1/__init__.py b/deepgram/clients/common/v1/__init__.py index 0cb91bc2..29f3b956 100644 --- a/deepgram/clients/common/v1/__init__.py +++ b/deepgram/clients/common/v1/__init__.py @@ -17,11 +17,8 @@ from .shared_response import ( BaseResponse, ModelInfo, - Word, - Alternative, Hit, Search, - Channel, ) from .rest_response import ( diff --git a/deepgram/clients/common/v1/shared_response.py b/deepgram/clients/common/v1/shared_response.py index fdf2b8ae..5342380e 100644 --- a/deepgram/clients/common/v1/shared_response.py +++ b/deepgram/clients/common/v1/shared_response.py @@ -58,47 +58,6 @@ class ModelInfo(BaseResponse): arch: str = "" -@dataclass -class Word(BaseResponse): - """ - Word object - """ - - word: str = "" - start: float = 0 - end: float = 0 - confidence: float = 0 - punctuated_word: Optional[str] = field( - default=None, metadata=dataclass_config(exclude=lambda f: f is None) - ) - speaker: Optional[int] = field( - default=None, metadata=dataclass_config(exclude=lambda f: f is None) - ) - language: Optional[str] = field( - default=None, metadata=dataclass_config(exclude=lambda f: f is None) - ) - - -@dataclass -class Alternative(BaseResponse): - """ - Alternative object - """ - - transcript: str = "" - confidence: float = 0 - words: List[Word] = field(default_factory=list) - languages: Optional[List[str]] = field( - default=None, metadata=dataclass_config(exclude=lambda f: f is None) - ) - - def __getitem__(self, key): - _dict = self.to_dict() - if "words" in _dict: - _dict["words"] = [Word.from_dict(words) for words in _dict["words"]] - return _dict[key] - - @dataclass class Hit(BaseResponse): """ @@ -125,26 +84,3 @@ def __getitem__(self, key): if "hits" in _dict: _dict["hits"] = [Hit.from_dict(hits) for hits in _dict["hits"]] return _dict[key] - - -@dataclass -class Channel(BaseResponse): - """ - Channel object - """ - - search: Optional[List[Search]] = field( - default=None, metadata=dataclass_config(exclude=lambda f: f is None) - ) - alternatives: List[Alternative] = field(default_factory=list) - - def __getitem__(self, key): - _dict = self.to_dict() - if "search" in _dict: - _dict["search"] = [Search.from_dict(search) for search in _dict["search"]] - if "alternatives" in _dict: - _dict["alternatives"] = [ - Alternative.from_dict(alternatives) - for alternatives in _dict["alternatives"] - ] - return _dict[key] diff --git a/deepgram/clients/listen/__init__.py b/deepgram/clients/listen/__init__.py index ff19b5a7..3a3285f5 100644 --- a/deepgram/clients/listen/__init__.py +++ b/deepgram/clients/listen/__init__.py @@ -52,11 +52,8 @@ TopicsInfo, # between rest and websocket ModelInfo, - Alternative, Hit, Search, - Channel, - Word, # unique Entity, ListenRESTMetadata, @@ -70,6 +67,9 @@ Translation, Utterance, Warning, + ListenRESTAlternative, + ListenRESTChannel, + ListenRESTWord, ) @@ -94,6 +94,9 @@ UnhandledResponse, # unique ListenWSMetadata, + ListenWSWord, + ListenWSAlternative, + ListenWSChannel, ) # clients diff --git a/deepgram/clients/listen/client.py b/deepgram/clients/listen/client.py index 71e69cdf..29b61bed 100644 --- a/deepgram/clients/listen/client.py +++ b/deepgram/clients/listen/client.py @@ -41,11 +41,8 @@ TopicsInfo as TopicsInfoLatest, # between rest and websocket ModelInfo as ModelInfoLatest, - Alternative as AlternativeLatest, Hit as HitLatest, Search as SearchLatest, - Channel as ChannelLatest, - Word as WordLatest, # unique ListenRESTMetadata as ListenRESTMetadataLatest, Entity as EntityLatest, @@ -59,6 +56,9 @@ Translation as TranslationLatest, Utterance as UtteranceLatest, Warning as WarningLatest, + ListenRESTAlternative as ListenRESTAlternativeLatest, + ListenRESTChannel as ListenRESTChannelLatest, + ListenRESTWord as ListenRESTWordLatest, ) # websocket @@ -80,6 +80,9 @@ ErrorResponse as ErrorResponseLatest, UnhandledResponse as UnhandledResponseLatest, ListenWSMetadata as ListenWSMetadataLatest, + ListenWSAlternative as ListenWSAlternativeLatest, + ListenWSChannel as ListenWSChannelLatest, + ListenWSWord as ListenWSWordLatest, ) # The vX/client.py points to the current supported version in the SDK. @@ -100,12 +103,9 @@ TopicsInfo = TopicsInfoLatest # between rest and websocket -Alternative = AlternativeLatest -Channel = ChannelLatest Hit = HitLatest ModelInfo = ModelInfoLatest Search = SearchLatest -Word = WordLatest # websocket common OpenResponse = OpenResponseLatest @@ -152,6 +152,9 @@ Translation = TranslationLatest Utterance = UtteranceLatest Warning = WarningLatest +ListenRESTAlternative = ListenRESTAlternativeLatest +ListenRESTChannel = ListenRESTChannelLatest +ListenRESTWord = ListenRESTWordLatest # websocket ## input @@ -166,7 +169,9 @@ ## unique ListenWSMetadata = ListenWSMetadataLatest - +ListenWSAlternative = ListenWSAlternativeLatest +ListenWSChannel = ListenWSChannelLatest +ListenWSWord = ListenWSWordLatest # clients ListenRESTClient = ListenRESTClientLatest diff --git a/deepgram/clients/listen/v1/__init__.py b/deepgram/clients/listen/v1/__init__.py index 455d0019..d1b2f3a6 100644 --- a/deepgram/clients/listen/v1/__init__.py +++ b/deepgram/clients/listen/v1/__init__.py @@ -31,11 +31,8 @@ # between rest and websocket from ...common import ( ModelInfo, - Alternative, Hit, Search, - Channel, - Word, ) # common websocket @@ -99,6 +96,9 @@ Translation, Utterance, Warning, + ListenRESTAlternative, + ListenRESTChannel, + ListenRESTWord, ) # websocket @@ -125,4 +125,7 @@ # Word, #### unique Metadata as ListenWSMetadata, + ListenWSWord, + ListenWSAlternative, + ListenWSChannel, ) diff --git a/deepgram/clients/listen/v1/rest/__init__.py b/deepgram/clients/listen/v1/rest/__init__.py index 088d3f74..8106a2dd 100644 --- a/deepgram/clients/listen/v1/rest/__init__.py +++ b/deepgram/clients/listen/v1/rest/__init__.py @@ -38,11 +38,8 @@ TopicsInfo, # between rest and websocket ModelInfo, - Alternative, Hit, Search, - Channel, - Word, # unique Entity, Metadata, @@ -56,4 +53,7 @@ Translation, Utterance, Warning, + ListenRESTAlternative, + ListenRESTChannel, + ListenRESTWord, ) diff --git a/deepgram/clients/listen/v1/rest/response.py b/deepgram/clients/listen/v1/rest/response.py index bbae04de..e24e9c2f 100644 --- a/deepgram/clients/listen/v1/rest/response.py +++ b/deepgram/clients/listen/v1/rest/response.py @@ -27,11 +27,8 @@ # between rest and websocket from ....common import ( ModelInfo, - Alternative, - Channel, Hit, Search, - Word, ) # Async Prerecorded Response Types: @@ -142,11 +139,24 @@ class SummaryV2(BaseResponse): @dataclass -class ListenRestWord(Word): # pylint: disable=too-many-instance-attributes +class ListenRESTWord(BaseResponse): # pylint: disable=too-many-instance-attributes """ The word information for the response. """ + word: str = "" + start: float = 0 + end: float = 0 + confidence: float = 0 + punctuated_word: Optional[str] = field( + default=None, metadata=dataclass_config(exclude=lambda f: f is None) + ) + speaker: Optional[int] = field( + default=None, metadata=dataclass_config(exclude=lambda f: f is None) + ) + language: Optional[str] = field( + default=None, metadata=dataclass_config(exclude=lambda f: f is None) + ) speaker_confidence: Optional[float] = field( default=None, metadata=dataclass_config(exclude=lambda f: f is None) ) @@ -270,7 +280,7 @@ class Utterance(BaseResponse): # pylint: disable=too-many-instance-attributes confidence: float = 0 channel: int = 0 transcript: str = "" - words: List[Word] = field(default_factory=list) + words: List[ListenRESTWord] = field(default_factory=list) speaker: Optional[int] = field( default=None, metadata=dataclass_config(exclude=lambda f: f is None) ) @@ -285,7 +295,9 @@ class Utterance(BaseResponse): # pylint: disable=too-many-instance-attributes def __getitem__(self, key): _dict = self.to_dict() if "words" in _dict: - _dict["words"] = [Word.from_dict(words) for words in _dict["words"]] + _dict["words"] = [ + ListenRESTWord.from_dict(words) for words in _dict["words"] + ] if "sentiment" in _dict: _dict["sentiment"] = Sentiment.from_dict(_dict["sentiment"]) return _dict[key] @@ -306,12 +318,15 @@ class Entity(BaseResponse): @dataclass class ListenRESTAlternative( - Alternative + BaseResponse ): # pylint: disable=too-many-instance-attributes """ The alternative information for the response. """ + transcript: str = "" + confidence: float = 0 + words: List[ListenRESTWord] = field(default_factory=list) summaries: Optional[List[SummaryV1]] = field( default=None, metadata=dataclass_config(exclude=lambda f: f is None) ) @@ -324,11 +339,16 @@ class ListenRESTAlternative( translations: Optional[List[Translation]] = field( default=None, metadata=dataclass_config(exclude=lambda f: f is None) ) + languages: Optional[List[str]] = field( + default=None, metadata=dataclass_config(exclude=lambda f: f is None) + ) def __getitem__(self, key): _dict = self.to_dict() if "words" in _dict: - _dict["words"] = [Word.from_dict(words) for words in _dict["words"]] + _dict["words"] = [ + ListenRESTWord.from_dict(words) for words in _dict["words"] + ] if "summaries" in _dict: _dict["summaries"] = [ SummaryV1.from_dict(summaries) for summaries in _dict["summaries"] @@ -348,7 +368,7 @@ def __getitem__(self, key): @dataclass -class ListenRESTChannel(Channel): +class ListenRESTChannel(BaseResponse): """ The channel information for the response. """ @@ -356,7 +376,7 @@ class ListenRESTChannel(Channel): search: Optional[List[Search]] = field( default=None, metadata=dataclass_config(exclude=lambda f: f is None) ) - alternatives: List[Alternative] = field(default_factory=list) + alternatives: List[ListenRESTAlternative] = field(default_factory=list) detected_language: Optional[str] = field( default=None, metadata=dataclass_config(exclude=lambda f: f is None) ) @@ -370,7 +390,7 @@ def __getitem__(self, key): _dict["search"] = [Search.from_dict(search) for search in _dict["search"]] if "alternatives" in _dict: _dict["alternatives"] = [ - Alternative.from_dict(alternatives) + ListenRESTAlternative.from_dict(alternatives) for alternatives in _dict["alternatives"] ] return _dict[key] @@ -382,7 +402,7 @@ class Results(BaseResponse): The results information for the response. """ - channels: Optional[List[Channel]] = field( + channels: Optional[List[ListenRESTChannel]] = field( default=None, metadata=dataclass_config(exclude=lambda f: f is None) ) utterances: Optional[List[Utterance]] = field( @@ -405,7 +425,7 @@ def __getitem__(self, key): _dict = self.to_dict() if "channels" in _dict: _dict["channels"] = [ - Channel.from_dict(channels) for channels in _dict["channels"] + ListenRESTChannel.from_dict(channels) for channels in _dict["channels"] ] if "utterances" in _dict: _dict["utterances"] = [ diff --git a/deepgram/clients/listen/v1/websocket/__init__.py b/deepgram/clients/listen/v1/websocket/__init__.py index 34c37936..9f6891d8 100644 --- a/deepgram/clients/listen/v1/websocket/__init__.py +++ b/deepgram/clients/listen/v1/websocket/__init__.py @@ -21,11 +21,11 @@ UnhandledResponse, #### between rest and websocket ModelInfo, - Alternative, Hit, Search, - Channel, - Word, #### unique Metadata, + ListenWSWord, + ListenWSAlternative, + ListenWSChannel, ) diff --git a/deepgram/clients/listen/v1/websocket/response.py b/deepgram/clients/listen/v1/websocket/response.py index a26a31c6..43cfe3e4 100644 --- a/deepgram/clients/listen/v1/websocket/response.py +++ b/deepgram/clients/listen/v1/websocket/response.py @@ -19,13 +19,78 @@ # between rest and websocket from ....common import ( ModelInfo, - Alternative, Hit, Search, - Channel, - Word, ) + +# unique + + +@dataclass +class ListenWSWord(BaseResponse): + """ + Word object + """ + + word: str = "" + start: float = 0 + end: float = 0 + confidence: float = 0 + punctuated_word: Optional[str] = field( + default=None, metadata=dataclass_config(exclude=lambda f: f is None) + ) + speaker: Optional[int] = field( + default=None, metadata=dataclass_config(exclude=lambda f: f is None) + ) + language: Optional[str] = field( + default=None, metadata=dataclass_config(exclude=lambda f: f is None) + ) + + +@dataclass +class ListenWSAlternative(BaseResponse): + """ + Alternative object + """ + + transcript: str = "" + confidence: float = 0 + words: List[ListenWSWord] = field(default_factory=list) + languages: Optional[List[str]] = field( + default=None, metadata=dataclass_config(exclude=lambda f: f is None) + ) + + def __getitem__(self, key): + _dict = self.to_dict() + if "words" in _dict: + _dict["words"] = [ListenWSWord.from_dict(words) for words in _dict["words"]] + return _dict[key] + + +@dataclass +class ListenWSChannel(BaseResponse): + """ + Channel object + """ + + search: Optional[List[Search]] = field( + default=None, metadata=dataclass_config(exclude=lambda f: f is None) + ) + alternatives: List[ListenWSAlternative] = field(default_factory=list) + + def __getitem__(self, key): + _dict = self.to_dict() + if "search" in _dict: + _dict["search"] = [Search.from_dict(search) for search in _dict["search"]] + if "alternatives" in _dict: + _dict["alternatives"] = [ + ListenWSAlternative.from_dict(alternatives) + for alternatives in _dict["alternatives"] + ] + return _dict[key] + + # unique @@ -62,7 +127,7 @@ class LiveResultResponse(BaseResponse): # pylint: disable=too-many-instance-att Result Message from the Deepgram Platform """ - channel: Channel + channel: ListenWSChannel metadata: Metadata type: str = "" channel_index: List[int] = field(default_factory=list) @@ -78,7 +143,7 @@ def __getitem__(self, key): _dict = self.to_dict() if "channel" in _dict: _dict["channel"] = [ - Channel.from_dict(channel) for channel in _dict["channel"] + ListenWSChannel.from_dict(channel) for channel in _dict["channel"] ] if "metadata" in _dict: _dict["metadata"] = [