Skip to content

Commit a291392

Browse files
authored
Don't swallow audio import errors (#302)
1 parent 8c0d59d commit a291392

File tree

4 files changed

+28
-19
lines changed

4 files changed

+28
-19
lines changed

poetry.lock

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ simpleaudio = { version = "^1.0.4", optional = true}
6767
sounddevice = { version = "^0.4.6", optional = true}
6868
typing_extensions = ">= 4.0.0"
6969
websockets = "^13.1"
70+
exceptiongroup = "^1.3.0"
7071

7172
[tool.poetry.dev-dependencies]
7273
mypy = "1.0.1"

src/hume/empathic_voice/chat/audio/audio_utilities.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,19 @@
33

44
import asyncio
55
from io import BytesIO
6+
from typing import Optional
7+
from exceptiongroup import ExceptionGroup
68

79
from hume.core.api_error import ApiError
810

11+
_import_error: Optional[ModuleNotFoundError] = None
912
try:
1013
import pydub.playback
1114
from pydub import AudioSegment
12-
_HAS_AUDIO_DEPENDENCIES = True
13-
except ModuleNotFoundError:
14-
_HAS_AUDIO_DEPENDENCIES = False
15+
except ModuleNotFoundError as e:
16+
_import_error = e
17+
18+
1519

1620

1721
# NOTE:
@@ -26,7 +30,7 @@ async def play_audio(byte_str: bytes) -> None:
2630
Args:
2731
byte_str (bytes): Byte string of audio data.
2832
"""
29-
if not _HAS_AUDIO_DEPENDENCIES:
30-
raise ApiError(body='Run `pip install "hume[microphone]"` to install dependencies required to use audio playback.')
33+
if _import_error:
34+
raise ExceptionGroup('Run `pip install "hume[microphone]"` to install dependencies required to use audio playback.', [_import_error])
3135
segment = AudioSegment.from_file(BytesIO(byte_str)) # type: ignore
3236
await asyncio.to_thread(pydub.playback.play, segment)

src/hume/empathic_voice/chat/audio/microphone.py

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,26 @@
88
import contextlib
99
import dataclasses
1010
import logging
11-
from typing import AsyncIterator, ClassVar, Iterator
11+
from typing import AsyncIterator, ClassVar, Iterator, List
12+
from exceptiongroup import ExceptionGroup
1213

1314
from hume.core.api_error import ApiError
1415
from hume.empathic_voice.chat.audio.asyncio_utilities import Stream
1516

17+
_FAILED_IMPORTS: List[ModuleNotFoundError] = []
18+
1619
try:
1720
import _cffi_backend as cffi_backend # type: ignore
18-
import sounddevice # type: ignore
1921
from _cffi_backend import \
2022
_CDataBase as CDataBase # pylint: disable=no-name-in-module
21-
from sounddevice import CallbackFlags, RawInputStream
22-
23-
_HAS_AUDIO_DEPENDENCIES = True
24-
except ModuleNotFoundError:
25-
_HAS_AUDIO_DEPENDENCIES = False
23+
except ModuleNotFoundError as e:
24+
_FAILED_IMPORTS.append(e)
2625

26+
try:
27+
import sounddevice # type: ignore
28+
from sounddevice import CallbackFlags, RawInputStream # type: ignore
29+
except ModuleNotFoundError as e:
30+
_FAILED_IMPORTS.append(e)
2731

2832
logger = logging.getLogger(__name__)
2933

@@ -50,8 +54,8 @@ def context(cls, *, device: int | None = DEFAULT_DEVICE) -> Iterator["Microphone
5054
Args:
5155
device (int | None): Input device ID.
5256
"""
53-
if not _HAS_AUDIO_DEPENDENCIES:
54-
raise ApiError(body='Run `pip install "hume[microphone]"` to install dependencies required to use microphone playback.')
57+
if _FAILED_IMPORTS:
58+
raise ExceptionGroup("Importing audio libraries failed. Ensure you have installed the hume[microphone] extra `pip install 'hume[microphone]'` to use audio features.", _FAILED_IMPORTS)
5559

5660
if device is None:
5761
device = sounddevice.default.device[0]

0 commit comments

Comments
 (0)