The collection of gRPC APIs for Techmo ASR solutions supplied as a Python package.
Run once after cloning to initialise the submodule:
./setup.sh- Python >=3.8
Example:
python3 -m venv .venv
source .venv/bin/activate
pip install --require-virtualenv --upgrade pip
pip install --require-virtualenv .For basic development use, consider convenient ./install.sh.
Proto stubs must be generated before running tests. Use ./install.sh once, then invoke tox:
./install.sh
uvx --with "tox-uv>=1" toxTo run a single Python version:
uvx --with "tox-uv>=1" tox -e py312The package provides a precompiled collection of .proto files that can be imported directly or through the alias modules.
Example:
- direct import
>>> from techmo.asr.api.v1p1 import asr_pb2 as api
>>> hasattr(api, "StreamingRecognizeRequest")
True- import from an alias module
>>> from asr_api import v1p1 as api
>>> hasattr(api, "StreamingRecognizeRequest")
TrueInvoking RPC simply requires to call a desired method on a stub object dedicated to a specific service.
Example:
import wave
import grpc
from asr_api import v1p1 as api
# This example assumes that the endpoint is an instance
# of techmo.asr.api.v1p1.Asr service listening on the local 30384 port.
grpc_service_address = "127.0.0.1:30384"
# Audio data come from a mono 16-bit linear PCM encoded WAV file.
audio_file = wave.open("audio.wav", "rb")
audio_bytes = audio_file.readframes(audio_file.getnframes())
audio_sampling_rate_hz = audio_file.getframerate()
with grpc.insecure_channel(grpc_service_address) as grpc_channel:
asr_stub = api.AsrStub(grpc_channel)
requests = (
api.StreamingRecognizeRequest(
config=api.StreamingRecognizeRequestConfig(
audio_config=api.AudioConfig(
encoding=api.AudioConfig.AudioEncoding.LINEAR16,
sampling_rate_hz=audio_sampling_rate_hz,
),
speech_recognition_config=api.SpeechRecognitionConfig(
enable_speech_recognition=True,
),
),
),
api.StreamingRecognizeRequest(
data=api.StreamingRecognizeRequestData(
audio=api.Audio(bytes=audio_bytes),
),
),
)
for response in asr_stub.StreamingRecognize(iter(requests)):
print(response)Even though samples are easier to work with, finally audio must be sent in its pure binary representation, not decoded as samples. To encode samples into bytes, the struct Python module comes in handy.
import struct
# Imagine that audio samples are an array of integers
# (mono signed little-endian 16-bit linear PCM encoded samples in this case).
audio_samples = []
audio_bytes = struct.pack(f"<{len(audio_samples)}h", *audio_samples)