Skip to content

Commit 23a5d58

Browse files
author
Stepan Rasputny
authored
feat: tests added (GoogleCloudPlatform#11775)
* feat: tests added * correcting issue with return from loop
1 parent 2e65782 commit 23a5d58

3 files changed

Lines changed: 90 additions & 6 deletions

File tree

speech/microphone/transcribe_streaming_infinite.py

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ def generator(self: object) -> object:
214214
yield b"".join(data)
215215

216216

217-
def listen_print_loop(responses: object, stream: object) -> object:
217+
def listen_print_loop(responses: object, stream: object) -> None:
218218
"""Iterates through server responses and prints them.
219219
220220
The responses passed is a generator that will block until a response
@@ -232,9 +232,6 @@ def listen_print_loop(responses: object, stream: object) -> object:
232232
Arg:
233233
responses: The responses returned from the API.
234234
stream: The audio stream to be processed.
235-
236-
Returns:
237-
The transcript of the result
238235
"""
239236
for response in responses:
240237
if get_current_time() - stream.start_time > STREAMING_LIMIT:
@@ -292,8 +289,6 @@ def listen_print_loop(responses: object, stream: object) -> object:
292289

293290
stream.last_transcript_was_final = False
294291

295-
return transcript
296-
297292

298293
def main() -> None:
299294
"""start bidirectional streaming from microphone input to speech API"""
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
# Copyright 2024 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
import os
16+
import re
17+
import threading
18+
import time
19+
20+
from unittest import mock
21+
22+
import pytest
23+
24+
RESOURCES = os.path.join(os.path.dirname(__file__), "resources")
25+
26+
27+
class MockPyAudio:
28+
def __init__(self: object, audio_filename: str) -> None:
29+
self.audio_filename = audio_filename
30+
31+
def __call__(self: object, *args: object) -> object:
32+
return self
33+
34+
def open(
35+
self: object,
36+
stream_callback: object,
37+
rate: int,
38+
*args: object,
39+
**kwargs: object
40+
) -> object:
41+
self.rate = rate
42+
self.closed = threading.Event()
43+
self.stream_thread = threading.Thread(
44+
target=self.stream_audio,
45+
args=(self.audio_filename, stream_callback, self.closed),
46+
)
47+
self.stream_thread.start()
48+
return self
49+
50+
def close(self: object) -> None:
51+
self.closed.set()
52+
53+
def stop_stream(self: object) -> None:
54+
pass
55+
56+
def terminate(self: object) -> None:
57+
pass
58+
59+
def stream_audio(
60+
self: object,
61+
audio_filename: str,
62+
callback: object,
63+
closed: object,
64+
num_frames: int = 512,
65+
) -> None:
66+
with open(audio_filename, "rb") as audio_file:
67+
while not closed.is_set():
68+
# Approximate realtime by sleeping for the appropriate time for
69+
# the requested number of frames
70+
time.sleep(num_frames / float(self.rate))
71+
# audio is 16-bit samples, whereas python byte is 8-bit
72+
num_bytes = 2 * num_frames
73+
chunk = audio_file.read(num_bytes) or b"\0" * num_bytes
74+
callback(chunk, None, None, None)
75+
76+
77+
@mock.patch.dict(
78+
"sys.modules",
79+
pyaudio=mock.MagicMock(PyAudio=MockPyAudio(os.path.join(RESOURCES, "quit.raw"))),
80+
)
81+
def test_main(capsys: pytest.CaptureFixture) -> None:
82+
import transcribe_streaming_infinite
83+
84+
transcribe_streaming_infinite.main()
85+
out, err = capsys.readouterr()
86+
87+
assert re.search(r"quit", out, re.DOTALL | re.I)

speech/microphone/transcribe_streaming_mic_test.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919

2020
from unittest import mock
2121

22+
import google.auth.transport.grpc # noqa: F401
23+
import google.auth.transport.requests # noqa: F401
2224
import pytest
2325

2426
RESOURCES = os.path.join(os.path.dirname(__file__), "resources")

0 commit comments

Comments
 (0)