Skip to content

Commit

Permalink
Implement Logging Levels for Supportability
Browse files Browse the repository at this point in the history
  • Loading branch information
dvonthenen committed Nov 30, 2023
1 parent 80b878d commit a4709c2
Show file tree
Hide file tree
Showing 16 changed files with 1,134 additions and 479 deletions.
71 changes: 60 additions & 11 deletions deepgram/audio/microphone/microphone.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@
import threading
import pyaudio
from array import array
from sys import byteorder
import logging, verboselogs

from .errors import DeepgramMicrophoneError

FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 16000
CHUNK = 8000
CHUNK = 8194


class Microphone:
Expand All @@ -23,8 +23,18 @@ class Microphone:
"""

def __init__(
self, push_callback, format=FORMAT, rate=RATE, chunk=CHUNK, channels=CHANNELS
self,
push_callback,
verbose=logging.WARNING,
format=FORMAT,
rate=RATE,
chunk=CHUNK,
channels=CHANNELS,
):
self.logger = logging.getLogger(__name__)
self.logger.addHandler(logging.StreamHandler())
self.logger.setLevel(verbose)

self.audio = pyaudio.PyAudio()
self.chunk = chunk
self.rate = rate
Expand All @@ -34,20 +44,36 @@ def __init__(
self.stream = None

def is_active(self):
self.logger.debug("Microphone.is_active ENTER")
if self.stream is None:
self.logger.error("stream is None")
self.logger.debug("Microphone.is_active LEAVE")
return False
return self.stream.is_active()

val = self.stream.is_active()
self.logger.info("is_active: %s", val)
self.logger.debug("Microphone.is_active LEAVE")
return

def start(self):
self.logger.debug("Microphone.start ENTER")

if self.stream is not None:
self.logger.error("stream is None")
self.logger.debug("Microphone.start LEAVE")
raise DeepgramMicrophoneError("Microphone already started")

self.logger.info("format: %s", self.format)
self.logger.info("channels: %d", self.channels)
self.logger.info("rate: %d", self.rate)
self.logger.info("chunk: %d", self.chunk)

self.stream = self.audio.open(
format=self.format,
channels=self.channels,
rate=self.rate,
input=True,
frames_per_buffer=CHUNK,
frames_per_buffer=self.chunk,
)

self.exit = False
Expand All @@ -57,7 +83,12 @@ def start(self):
self.thread = threading.Thread(target=self.processing)
self.thread.start()

self.logger.notice("start succeeded")
self.logger.debug("Microphone.start LEAVE")

def processing(self):
self.logger.debug("Microphone.processing ENTER")

try:
while True:
data = self.stream.read(self.chunk)
Expand All @@ -66,27 +97,45 @@ def processing(self):
localExit = self.exit
self.lock.release()
if localExit:
self.logger.info("exit is True")
break
if data is None:
self.logger.info("data is None")
continue

if inspect.iscoroutinefunction(self.push_callback):
self.logger.verbose("async/await callback")
asyncio.run(self.push_callback(data))
else:
self.logger.verbose("regular threaded callback")
self.push_callback(data)

self.logger.notice("processing exiting...")
self.logger.debug("Microphone.processing LEAVE")

except Exception as e:
print(f"Error while sending: {str(e)}")
self.logger.error("Error while sending: %s", str(e))
self.logger.debug("Microphone.processing LEAVE")
raise

def finish(self):
self.logger.debug("Microphone.finish ENTER")

self.lock.acquire()
self.logger.notice("signal exit")
self.exit = True
self.lock.release()

self.thread.join()
self.thread = None
if self.thread is not None:
self.thread.join()
self.thread = None
self.logger.notice("processing/send thread joined")

self.stream.stop_stream()
self.stream.close()
self.stream = None
if self.stream is not None:
self.stream.stop_stream()
self.stream.close()
self.stream = None
self.logger.notice("stream/recv thread joined")

self.logger.notice("finish succeeded")
self.logger.debug("Microphone.finish LEAVE")
30 changes: 25 additions & 5 deletions deepgram/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@

from typing import Optional
from importlib import import_module
import logging, verboselogs

from .clients.listen import ListenClient
from .clients.listen import ListenClient, PreRecordedClient
from .clients.manage.client import ManageClient
from .clients.onprem.client import OnPremClient

Expand All @@ -30,10 +31,13 @@ class DeepgramClient:
listen: Returns a ListenClient instance for interacting with Deepgram's transcription services.
manage: Returns a ManageClient instance for managing Deepgram resources.
onprem: Returns an OnPremClient instance for interacting with Deepgram's on-premises API.
"""

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:
raise DeepgramApiKeyError("Deepgram API key is required")

Expand All @@ -44,6 +48,8 @@ def __init__(self, api_key: str, config: Optional[DeepgramClientOptions] = None)
config.set_apikey(self.api_key)
self.config = config

self.logger.setLevel(logging.SPAM)

@property
def listen(self):
return ListenClient(self.config)
Expand All @@ -59,6 +65,9 @@ def onprem(self):
# INTERNAL CLASSES
class Version:
def __init__(self, config, parent: str):
self.logger = logging.getLogger(__name__)
self.logger.addHandler(logging.StreamHandler())
self.logger.setLevel(config.verbose)
self.config = config
self.parent = parent

Expand All @@ -75,8 +84,11 @@ def __init__(self, config, parent: str):
# raise DeepgramModuleError("Invalid parent")

def v(self, version: str = ""):
# print(f"version: {version}")
self.logger.debug("Version.v ENTER")
self.logger.info("version: %s", version)
if len(version) == 0:
self.logger.error("version is empty")
self.logger.debug("Version.v LEAVE")
raise DeepgramModuleError("Invalid module version")

className = ""
Expand All @@ -86,22 +98,30 @@ def v(self, version: str = ""):
case "onprem":
className = "OnPremClient"
case _:
self.logger.error("parent unknown: %s", self.parent)
self.logger.debug("Version.v LEAVE")
raise DeepgramModuleError("Invalid parent type")

# create class path
path = f"deepgram.clients.{self.parent}.v{version}.client"
# print(f"path: {path}")
# print(f"className: {className}")
self.logger.info("path: %s", path)
self.logger.info("className: %s", className)

# import class
mod = import_module(path)
if mod is None:
self.logger.error("module path is None")
self.logger.debug("Version.v LEAVE")
raise DeepgramModuleError("Unable to find package")

my_class = getattr(mod, className)
if my_class is None:
self.logger.error("my_class is None")
self.logger.debug("Version.v LEAVE")
raise DeepgramModuleError("Unable to find class")

# instantiate class
myClass = my_class(self.config)
self.logger.notice("Version.v succeeded")
self.logger.debug("Version.v LEAVE")
return myClass
21 changes: 18 additions & 3 deletions deepgram/clients/listen.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# SPDX-License-Identifier: MIT

from importlib import import_module
import logging, verboselogs

from ..options import DeepgramClientOptions

Expand Down Expand Up @@ -30,6 +31,9 @@ def legacylive(self):
# INTERNAL CLASSES
class Version:
def __init__(self, config, parent: str):
self.logger = logging.getLogger(__name__)
self.logger.addHandler(logging.StreamHandler())
self.logger.setLevel(config.verbose)
self.config = config
self.parent = parent

Expand All @@ -46,8 +50,11 @@ def __init__(self, config, parent: str):
# raise DeepgramModuleError("Invalid parent")

def v(self, version: str = ""):
# print(f"version: {version}")
self.logger.debug("Version.v ENTER")
self.logger.info("version: %s", version)
if len(version) == 0:
self.logger.error("version is empty")
self.logger.debug("Version.v LEAVE")
raise DeepgramModuleError("Invalid module version")

className = ""
Expand All @@ -57,22 +64,30 @@ def v(self, version: str = ""):
case "prerecorded":
className = "PreRecordedClient"
case _:
self.logger.error("parent unknown: %s", self.parent)
self.logger.debug("Version.v LEAVE")
raise DeepgramModuleError("Invalid parent type")

# create class path
path = f"deepgram.clients.{self.parent}.v{version}.client"
# print(f"path: {path}")
# print(f"className: {className}")
self.logger.info("path: %s", path)
self.logger.info("className: %s", className)

# import class
mod = import_module(path)
if mod is None:
self.logger.error("module path is None")
self.logger.debug("Version.v LEAVE")
raise DeepgramModuleError("Unable to find package")

my_class = getattr(mod, className)
if my_class is None:
self.logger.error("my_class is None")
self.logger.debug("Version.v LEAVE")
raise DeepgramModuleError("Unable to find class")

# instantiate class
myClass = my_class(self.config)
self.logger.notice("Version.v succeeded")
self.logger.debug("Version.v LEAVE")
return myClass
Loading

0 comments on commit a4709c2

Please sign in to comment.