bodhi-api-sdk 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Navana Tech India Private Limited
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,265 @@
1
+ Metadata-Version: 2.4
2
+ Name: bodhi-api-sdk
3
+ Version: 1.0.0
4
+ Summary: Bodhi API Python SDK for Streaming Speech Recognition
5
+ Home-page: https://github.com/navana-tech/bodhi-python-sdk
6
+ Author: Navana
7
+ Classifier: Programming Language :: Python :: 3
8
+ Classifier: License :: OSI Approved :: MIT License
9
+ Classifier: Operating System :: OS Independent
10
+ Requires-Python: >=3.7
11
+ Description-Content-Type: text/markdown
12
+ License-File: LICENSE
13
+ Requires-Dist: requests
14
+ Requires-Dist: aiohttp
15
+ Provides-Extra: pipecat
16
+ Requires-Dist: pipecat-ai>=1.4; extra == "pipecat"
17
+ Dynamic: author
18
+ Dynamic: classifier
19
+ Dynamic: description
20
+ Dynamic: description-content-type
21
+ Dynamic: home-page
22
+ Dynamic: license-file
23
+ Dynamic: provides-extra
24
+ Dynamic: requires-dist
25
+ Dynamic: requires-python
26
+ Dynamic: summary
27
+
28
+ # Bodhi API Python SDK
29
+
30
+ Bodhi API Python SDK provides a client for Navana's streaming speech recognition API.
31
+
32
+ ## Installation
33
+
34
+ ```bash
35
+ pip install bodhi-api-sdk
36
+ ```
37
+
38
+ ### Moving from `bodhi-sdk`
39
+
40
+ `bodhi-api-sdk` is the SDK for Bodhi's new API platform. Your imports do not
41
+ change — only the package you install, and the credentials you pass:
42
+
43
+ ```bash
44
+ pip uninstall bodhi-sdk
45
+ pip install bodhi-api-sdk
46
+ ```
47
+
48
+ ```python
49
+ # before, with bodhi-sdk
50
+ from bodhi import BodhiClient
51
+ client = BodhiClient(api_key=API_KEY, customer_id=CUSTOMER_ID)
52
+
53
+ # now, with bodhi-api-sdk
54
+ from bodhi import BodhiClient
55
+ client = BodhiClient(api_key=API_KEY)
56
+ ```
57
+
58
+ Drop `customer_id` and you are done. Classes, methods, events, config fields and
59
+ `BODHI_API_KEY` are all unchanged. The default endpoint is now
60
+ `wss://stt.navana.ai`.
61
+
62
+ **Uninstall `bodhi-sdk` first.** Both packages install the same `bodhi` module,
63
+ so they cannot be installed at the same time — installing one on top of the
64
+ other leaves you with a mix of the two. `bodhi-sdk` 1.4.x keeps working against
65
+ the old endpoint and will be retired once everyone has moved across.
66
+
67
+ ## Usage
68
+
69
+ To use the Bodhi Python SDK, follow these steps:
70
+
71
+ 1. **Installation:**
72
+ Install the SDK using pip:
73
+
74
+ ```bash
75
+ pip install bodhi-api-sdk
76
+ ```
77
+
78
+ 2. **Initialization:**
79
+ Create a `BodhiClient` instance with your API key:
80
+
81
+ ```python
82
+ from bodhi import BodhiClient
83
+
84
+ client = BodhiClient(api_key="YOUR_API_KEY")
85
+ ```
86
+
87
+ 3. **Transcription:**
88
+ Use the client methods to transcribe audio. The SDK supports transcription from local files, remote URLs, and streams.
89
+
90
+ - **Local File Transcription:**
91
+
92
+ ```python
93
+ config = TranscriptionConfig(
94
+ model="hi-banking-v2-8khz",
95
+ at_start_lid=False, # Enable language identification at start (default: False)
96
+ transliterate=False, # Enable transliteration output (default: False)
97
+ endpoint_silence_duration=0.6, # Trailing silence before an utterance
98
+ # is finalised, in seconds. Omitted
99
+ # unless set; server default 0.44,
100
+ # clamped to 0.44-1.2
101
+ )
102
+ response = client.transcribe_local_file(audio_file_path, config=config)
103
+ print(response.text)
104
+ ```
105
+
106
+ - **Remote URL Transcription:**
107
+
108
+ ```python
109
+ config = TranscriptionConfig(
110
+ model="hi-banking-v2-8khz",
111
+ at_start_lid=False, # Enable language identification at start (default: False)
112
+ transliterate=False, # Enable transliteration output (default: False)
113
+ endpoint_silence_duration=0.6, # Trailing silence before an utterance
114
+ # is finalised, in seconds. Omitted
115
+ # unless set; server default 0.44,
116
+ # clamped to 0.44-1.2
117
+ )
118
+ response = client.transcribe_remote_url("http://example.com/audio.wav", config)
119
+ print(response.text)
120
+ ```
121
+
122
+ - **Streaming Transcription:**
123
+ Refer to the examples for detailed instructions on setting up streaming transcription.
124
+
125
+ 4. **Event Handling:**
126
+ You can register event listeners to handle different stages of the transcription process using the `client.on` method and the `LiveTranscriptionEvents` enum. This is particularly useful for streaming and remote URL transcriptions where events are emitted asynchronously.
127
+
128
+ ```python
129
+ from bodhi import LiveTranscriptionEvents
130
+
131
+ async def on_transcript(response):
132
+ print(f"Transcript: {response.text}")
133
+
134
+ async def on_utterance_end(response):
135
+ print(f"UtteranceEnd: {response}")
136
+
137
+ async def on_speech_started(response):
138
+ print(f"SpeechStarted: {response}")
139
+
140
+ async def on_error(e):
141
+ print(f"Error: {str(e)}")
142
+
143
+ client.on(LiveTranscriptionEvents.Transcript, on_transcript)
144
+ client.on(LiveTranscriptionEvents.UtteranceEnd, on_utterance_end)
145
+ client.on(LiveTranscriptionEvents.SpeechStarted, on_speech_started)
146
+ client.on(LiveTranscriptionEvents.Error, on_error)
147
+ ```
148
+
149
+ Common events include:
150
+
151
+ - `LiveTranscriptionEvents.Transcript`: Emitted when a new transcription segment is available.
152
+ - `LiveTranscriptionEvents.UtteranceEnd`: Emitted when an utterance is detected as complete.
153
+ - `LiveTranscriptionEvents.SpeechStarted`: Emitted when speech activity is detected.
154
+ - `LiveTranscriptionEvents.Error`: Emitted when an error occurs during transcription.
155
+ - `LiveTranscriptionEvents.Close`: Emitted when the WebSocket connection is closed.
156
+
157
+ ## Pipecat integration
158
+
159
+ Building a voice agent with [Pipecat](https://github.com/pipecat-ai/pipecat)? Bodhi
160
+ drops into the STT slot of a Pipecat pipeline:
161
+
162
+ ```bash
163
+ pip install "bodhi-api-sdk[pipecat]"
164
+ ```
165
+
166
+ ```python
167
+ import os
168
+
169
+ from pipecat.pipeline.pipeline import Pipeline
170
+
171
+ from bodhi.integrations.pipecat_stt import BodhiHotword, BodhiSTTService
172
+
173
+ stt = BodhiSTTService(
174
+ api_key=os.environ["BODHI_API_KEY"],
175
+ model="hi-general-v2-8khz",
176
+ settings=BodhiSTTService.Settings(
177
+ parse_number=True, # normalise numbers, dates, currency
178
+ endpoint_silence_duration=0.6, # server-side endpointing, 0.44-1.2s
179
+ hotwords=[BodhiHotword("बजाज फिनसर्व", 2.0)],
180
+ ),
181
+ )
182
+
183
+ pipeline = Pipeline([
184
+ transport.input(),
185
+ stt,
186
+ context_aggregator.user(),
187
+ llm,
188
+ tts,
189
+ transport.output(),
190
+ ])
191
+ ```
192
+
193
+ That is the whole integration — `api_key` and `model` are the only
194
+ required arguments, and `url` defaults to `wss://stt.navana.ai`. Bodhi's
195
+ partial results arrive as `InterimTranscriptionFrame`s and its endpointed final
196
+ results as `TranscriptionFrame`s, so interruption handling and turn taking work
197
+ exactly as they do with any other Pipecat STT service.
198
+
199
+ Maintained by [Navana Tech](https://navana.ai/), who build Bodhi.
200
+
201
+ Written for pipecat-ai 1.4 and verified on 1.4.0 and 1.8.1. Streaming and
202
+ transcripts also work as far back as 1.0.0; switching model or hotwords at
203
+ runtime needs 1.4+, since that is where Pipecat's reconnect hook arrived. Needs
204
+ Python 3.10+, as Pipecat does.
205
+
206
+ If you pin `pipecat-ai` below 1.4, install plain `bodhi-api-sdk` (so pip doesn't
207
+ touch your pin) and import the same module, or copy
208
+ `bodhi/integrations/pipecat_stt.py` into your project — it is self-contained and
209
+ imports nothing else from this SDK.
210
+
211
+ ### Advanced features
212
+
213
+ Every field from the streaming
214
+ [advanced features](https://docs.navana.ai/speech-to-text/advanced-features/)
215
+ page is reachable from here:
216
+
217
+ | Bodhi feature | How to set it |
218
+ |---|---|
219
+ | Context biasing (hotwords) | `Settings(hotwords=[BodhiHotword("phrase", 2.0)])` |
220
+ | Endpoint silence threshold | `Settings(endpoint_silence_duration=0.6)` — seconds; server default 0.44, clamped to 0.44–1.2 |
221
+ | Parse numbers into numerals | `Settings(parse_number=True)` |
222
+ | Partial result exclusion | `BodhiSTTService(..., interim_results=False)` — also stops the server sending them |
223
+ | Aux metadata | `BodhiSTTService(..., aux=True)` |
224
+ | Confidence and word timings | already on every frame's `result` |
225
+ | Confidence filtering | `BodhiSTTService(..., min_confidence=0.5)` — Pipecat's guidance; `0` keeps everything |
226
+
227
+ `result` carries the raw Bodhi message, so word timings and confidence are
228
+ there on every final without setting any flag:
229
+
230
+ ```python
231
+ segment = frame.result["segment_meta"]
232
+ segment["confidence"] # 0.87 — utterance level
233
+ segment["words"][0] # {"word": "आपने", "confidence": 0.873,
234
+ # "start_time": 0.32, "end_time": 0.48}
235
+ ```
236
+
237
+ `aux=True` adds an `aux_info` block on top of that, with `request_time`,
238
+ `eot_wait_time` and `processed_audio_duration` for latency debugging.
239
+
240
+ ### Trying it out
241
+
242
+ Two runnable examples, neither needing an LLM or TTS key:
243
+
244
+ ```bash
245
+ export BODHI_API_KEY=...
246
+
247
+ # 1. Transcribe a recording through a real Pipecat pipeline.
248
+ curl -O https://stt.navana.ai/audios/loan.wav
249
+ python -m bodhi.examples.pipecat_stream_wav loan.wav --model hi-banking-v2-8khz
250
+
251
+ # 2. Transcribe your microphone live in the browser.
252
+ pip install "pipecat-ai[webrtc,silero,runner]"
253
+ python -m bodhi.examples.pipecat_mic_bot # then open http://localhost:7860/client
254
+ ```
255
+
256
+ For a full talking bot, follow the
257
+ [Pipecat quickstart](https://docs.pipecat.ai/pipecat/get-started/quickstart) and
258
+ replace its `DeepgramSTTService(...)` line with the `BodhiSTTService(...)` above.
259
+
260
+ `docs/pipecat-listing/bodhi.mdx` is this integration's service page for
261
+ docs.pipecat.ai, submitted as a
262
+ [community integration](https://github.com/pipecat-ai/pipecat/blob/main/COMMUNITY_INTEGRATIONS.md).
263
+ Keep it in step with the parameters above.
264
+
265
+ For complete code examples and detailed usage instructions for various scenarios, please refer to the [official documentation](https://docs.navana.ai/introduction/).
@@ -0,0 +1,238 @@
1
+ # Bodhi API Python SDK
2
+
3
+ Bodhi API Python SDK provides a client for Navana's streaming speech recognition API.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pip install bodhi-api-sdk
9
+ ```
10
+
11
+ ### Moving from `bodhi-sdk`
12
+
13
+ `bodhi-api-sdk` is the SDK for Bodhi's new API platform. Your imports do not
14
+ change — only the package you install, and the credentials you pass:
15
+
16
+ ```bash
17
+ pip uninstall bodhi-sdk
18
+ pip install bodhi-api-sdk
19
+ ```
20
+
21
+ ```python
22
+ # before, with bodhi-sdk
23
+ from bodhi import BodhiClient
24
+ client = BodhiClient(api_key=API_KEY, customer_id=CUSTOMER_ID)
25
+
26
+ # now, with bodhi-api-sdk
27
+ from bodhi import BodhiClient
28
+ client = BodhiClient(api_key=API_KEY)
29
+ ```
30
+
31
+ Drop `customer_id` and you are done. Classes, methods, events, config fields and
32
+ `BODHI_API_KEY` are all unchanged. The default endpoint is now
33
+ `wss://stt.navana.ai`.
34
+
35
+ **Uninstall `bodhi-sdk` first.** Both packages install the same `bodhi` module,
36
+ so they cannot be installed at the same time — installing one on top of the
37
+ other leaves you with a mix of the two. `bodhi-sdk` 1.4.x keeps working against
38
+ the old endpoint and will be retired once everyone has moved across.
39
+
40
+ ## Usage
41
+
42
+ To use the Bodhi Python SDK, follow these steps:
43
+
44
+ 1. **Installation:**
45
+ Install the SDK using pip:
46
+
47
+ ```bash
48
+ pip install bodhi-api-sdk
49
+ ```
50
+
51
+ 2. **Initialization:**
52
+ Create a `BodhiClient` instance with your API key:
53
+
54
+ ```python
55
+ from bodhi import BodhiClient
56
+
57
+ client = BodhiClient(api_key="YOUR_API_KEY")
58
+ ```
59
+
60
+ 3. **Transcription:**
61
+ Use the client methods to transcribe audio. The SDK supports transcription from local files, remote URLs, and streams.
62
+
63
+ - **Local File Transcription:**
64
+
65
+ ```python
66
+ config = TranscriptionConfig(
67
+ model="hi-banking-v2-8khz",
68
+ at_start_lid=False, # Enable language identification at start (default: False)
69
+ transliterate=False, # Enable transliteration output (default: False)
70
+ endpoint_silence_duration=0.6, # Trailing silence before an utterance
71
+ # is finalised, in seconds. Omitted
72
+ # unless set; server default 0.44,
73
+ # clamped to 0.44-1.2
74
+ )
75
+ response = client.transcribe_local_file(audio_file_path, config=config)
76
+ print(response.text)
77
+ ```
78
+
79
+ - **Remote URL Transcription:**
80
+
81
+ ```python
82
+ config = TranscriptionConfig(
83
+ model="hi-banking-v2-8khz",
84
+ at_start_lid=False, # Enable language identification at start (default: False)
85
+ transliterate=False, # Enable transliteration output (default: False)
86
+ endpoint_silence_duration=0.6, # Trailing silence before an utterance
87
+ # is finalised, in seconds. Omitted
88
+ # unless set; server default 0.44,
89
+ # clamped to 0.44-1.2
90
+ )
91
+ response = client.transcribe_remote_url("http://example.com/audio.wav", config)
92
+ print(response.text)
93
+ ```
94
+
95
+ - **Streaming Transcription:**
96
+ Refer to the examples for detailed instructions on setting up streaming transcription.
97
+
98
+ 4. **Event Handling:**
99
+ You can register event listeners to handle different stages of the transcription process using the `client.on` method and the `LiveTranscriptionEvents` enum. This is particularly useful for streaming and remote URL transcriptions where events are emitted asynchronously.
100
+
101
+ ```python
102
+ from bodhi import LiveTranscriptionEvents
103
+
104
+ async def on_transcript(response):
105
+ print(f"Transcript: {response.text}")
106
+
107
+ async def on_utterance_end(response):
108
+ print(f"UtteranceEnd: {response}")
109
+
110
+ async def on_speech_started(response):
111
+ print(f"SpeechStarted: {response}")
112
+
113
+ async def on_error(e):
114
+ print(f"Error: {str(e)}")
115
+
116
+ client.on(LiveTranscriptionEvents.Transcript, on_transcript)
117
+ client.on(LiveTranscriptionEvents.UtteranceEnd, on_utterance_end)
118
+ client.on(LiveTranscriptionEvents.SpeechStarted, on_speech_started)
119
+ client.on(LiveTranscriptionEvents.Error, on_error)
120
+ ```
121
+
122
+ Common events include:
123
+
124
+ - `LiveTranscriptionEvents.Transcript`: Emitted when a new transcription segment is available.
125
+ - `LiveTranscriptionEvents.UtteranceEnd`: Emitted when an utterance is detected as complete.
126
+ - `LiveTranscriptionEvents.SpeechStarted`: Emitted when speech activity is detected.
127
+ - `LiveTranscriptionEvents.Error`: Emitted when an error occurs during transcription.
128
+ - `LiveTranscriptionEvents.Close`: Emitted when the WebSocket connection is closed.
129
+
130
+ ## Pipecat integration
131
+
132
+ Building a voice agent with [Pipecat](https://github.com/pipecat-ai/pipecat)? Bodhi
133
+ drops into the STT slot of a Pipecat pipeline:
134
+
135
+ ```bash
136
+ pip install "bodhi-api-sdk[pipecat]"
137
+ ```
138
+
139
+ ```python
140
+ import os
141
+
142
+ from pipecat.pipeline.pipeline import Pipeline
143
+
144
+ from bodhi.integrations.pipecat_stt import BodhiHotword, BodhiSTTService
145
+
146
+ stt = BodhiSTTService(
147
+ api_key=os.environ["BODHI_API_KEY"],
148
+ model="hi-general-v2-8khz",
149
+ settings=BodhiSTTService.Settings(
150
+ parse_number=True, # normalise numbers, dates, currency
151
+ endpoint_silence_duration=0.6, # server-side endpointing, 0.44-1.2s
152
+ hotwords=[BodhiHotword("बजाज फिनसर्व", 2.0)],
153
+ ),
154
+ )
155
+
156
+ pipeline = Pipeline([
157
+ transport.input(),
158
+ stt,
159
+ context_aggregator.user(),
160
+ llm,
161
+ tts,
162
+ transport.output(),
163
+ ])
164
+ ```
165
+
166
+ That is the whole integration — `api_key` and `model` are the only
167
+ required arguments, and `url` defaults to `wss://stt.navana.ai`. Bodhi's
168
+ partial results arrive as `InterimTranscriptionFrame`s and its endpointed final
169
+ results as `TranscriptionFrame`s, so interruption handling and turn taking work
170
+ exactly as they do with any other Pipecat STT service.
171
+
172
+ Maintained by [Navana Tech](https://navana.ai/), who build Bodhi.
173
+
174
+ Written for pipecat-ai 1.4 and verified on 1.4.0 and 1.8.1. Streaming and
175
+ transcripts also work as far back as 1.0.0; switching model or hotwords at
176
+ runtime needs 1.4+, since that is where Pipecat's reconnect hook arrived. Needs
177
+ Python 3.10+, as Pipecat does.
178
+
179
+ If you pin `pipecat-ai` below 1.4, install plain `bodhi-api-sdk` (so pip doesn't
180
+ touch your pin) and import the same module, or copy
181
+ `bodhi/integrations/pipecat_stt.py` into your project — it is self-contained and
182
+ imports nothing else from this SDK.
183
+
184
+ ### Advanced features
185
+
186
+ Every field from the streaming
187
+ [advanced features](https://docs.navana.ai/speech-to-text/advanced-features/)
188
+ page is reachable from here:
189
+
190
+ | Bodhi feature | How to set it |
191
+ |---|---|
192
+ | Context biasing (hotwords) | `Settings(hotwords=[BodhiHotword("phrase", 2.0)])` |
193
+ | Endpoint silence threshold | `Settings(endpoint_silence_duration=0.6)` — seconds; server default 0.44, clamped to 0.44–1.2 |
194
+ | Parse numbers into numerals | `Settings(parse_number=True)` |
195
+ | Partial result exclusion | `BodhiSTTService(..., interim_results=False)` — also stops the server sending them |
196
+ | Aux metadata | `BodhiSTTService(..., aux=True)` |
197
+ | Confidence and word timings | already on every frame's `result` |
198
+ | Confidence filtering | `BodhiSTTService(..., min_confidence=0.5)` — Pipecat's guidance; `0` keeps everything |
199
+
200
+ `result` carries the raw Bodhi message, so word timings and confidence are
201
+ there on every final without setting any flag:
202
+
203
+ ```python
204
+ segment = frame.result["segment_meta"]
205
+ segment["confidence"] # 0.87 — utterance level
206
+ segment["words"][0] # {"word": "आपने", "confidence": 0.873,
207
+ # "start_time": 0.32, "end_time": 0.48}
208
+ ```
209
+
210
+ `aux=True` adds an `aux_info` block on top of that, with `request_time`,
211
+ `eot_wait_time` and `processed_audio_duration` for latency debugging.
212
+
213
+ ### Trying it out
214
+
215
+ Two runnable examples, neither needing an LLM or TTS key:
216
+
217
+ ```bash
218
+ export BODHI_API_KEY=...
219
+
220
+ # 1. Transcribe a recording through a real Pipecat pipeline.
221
+ curl -O https://stt.navana.ai/audios/loan.wav
222
+ python -m bodhi.examples.pipecat_stream_wav loan.wav --model hi-banking-v2-8khz
223
+
224
+ # 2. Transcribe your microphone live in the browser.
225
+ pip install "pipecat-ai[webrtc,silero,runner]"
226
+ python -m bodhi.examples.pipecat_mic_bot # then open http://localhost:7860/client
227
+ ```
228
+
229
+ For a full talking bot, follow the
230
+ [Pipecat quickstart](https://docs.pipecat.ai/pipecat/get-started/quickstart) and
231
+ replace its `DeepgramSTTService(...)` line with the `BodhiSTTService(...)` above.
232
+
233
+ `docs/pipecat-listing/bodhi.mdx` is this integration's service page for
234
+ docs.pipecat.ai, submitted as a
235
+ [community integration](https://github.com/pipecat-ai/pipecat/blob/main/COMMUNITY_INTEGRATIONS.md).
236
+ Keep it in step with the parameters above.
237
+
238
+ For complete code examples and detailed usage instructions for various scenarios, please refer to the [official documentation](https://docs.navana.ai/introduction/).
@@ -0,0 +1,23 @@
1
+ """
2
+ Bodhi Python SDK - Streaming Speech Recognition
3
+ """
4
+
5
+ __version__ = "1.0.0"
6
+
7
+ EOF_SIGNAL = '{"eof": 1}'
8
+
9
+ from .transcription_client import BodhiClient
10
+ from .transcription_config import TranscriptionConfig, Hotword
11
+ from .transcription_response import TranscriptionResponse
12
+ from .events import LiveTranscriptionEvents
13
+ from bodhi.utils.error_utils import BodhiErrors
14
+
15
+ __all__ = [
16
+ "BodhiClient",
17
+ "TranscriptionConfig",
18
+ "TranscriptionResponse",
19
+ "Hotword",
20
+ "LiveTranscriptionEvents",
21
+ "EOF_SIGNAL",
22
+ BodhiErrors,
23
+ ]
@@ -0,0 +1,54 @@
1
+ """Audio Processing Module for Bodhi Client"""
2
+
3
+ import wave
4
+ import asyncio
5
+ from typing import BinaryIO, Any
6
+ from .utils.logger import logger
7
+ from . import EOF_SIGNAL
8
+
9
+
10
+ class AudioProcessor:
11
+ @staticmethod
12
+ async def process_file(
13
+ ws: Any,
14
+ wf: wave.Wave_read,
15
+ ) -> None:
16
+ """Process and stream audio file data.
17
+
18
+ Args:
19
+ ws: WebSocket connection
20
+ wf: Wave file object
21
+ """
22
+ try:
23
+
24
+ REALTIME_RESOLUTION = 0.02 # 20ms
25
+ byte_rate = wf.getframerate() * wf.getsampwidth() * wf.getnchannels()
26
+ data = wf.readframes(wf.getnframes())
27
+ audio_cursor = 0
28
+
29
+ while len(data):
30
+ i = int(byte_rate * REALTIME_RESOLUTION)
31
+ chunk, data = data[:i], data[i:]
32
+ if not ws.closed:
33
+ await ws.send_bytes(chunk)
34
+ logger.debug(f"Sent {len(chunk)} bytes of audio data")
35
+ audio_cursor += REALTIME_RESOLUTION
36
+ await asyncio.sleep(REALTIME_RESOLUTION)
37
+
38
+ if not ws.closed:
39
+ await ws.send_str(EOF_SIGNAL)
40
+ logger.debug("Sent EOF signal")
41
+ except Exception as e:
42
+ return e
43
+
44
+ @staticmethod
45
+ async def process_stream(stream: BinaryIO, ws: Any) -> None:
46
+ """Process and stream generic binary stream data."""
47
+ try:
48
+ data = stream.read()
49
+ if not ws.closed:
50
+ await ws.send_bytes(data)
51
+ logger.debug(f"Sent {len(data)} bytes of stream data")
52
+ except Exception as e:
53
+ logger.exception("Error during stream processing")
54
+ raise e
@@ -0,0 +1,9 @@
1
+ from enum import Enum
2
+
3
+
4
+ class LiveTranscriptionEvents(Enum):
5
+ Transcript = "Transcript"
6
+ UtteranceEnd = "UtteranceEnd"
7
+ SpeechStarted = "SpeechStarted"
8
+ Error = "Error"
9
+ Close = "Close"
@@ -0,0 +1,7 @@
1
+ """Runnable examples for the Bodhi SDK integrations.
2
+
3
+ Each module runs as a script, so nothing needs cloning:
4
+
5
+ python -m bodhi.examples.pipecat_mic_bot
6
+ python -m bodhi.examples.pipecat_stream_wav call.wav
7
+ """