# Python Speechly API
See the generic [Speechly gRPC stubs documentation](https://github.com/speechly/api) for more information about using the API.
A complete example on how to stream audio from a file to the Speechly API can be found in [speechly_grpc_example.py](https://github.com/speechly/api/blob/master/python/speechly_grpc_example.py).
## Install
Install the latest package using `pip`:
pip install speechly-api
Note that the minimum python version supported is 3.6.
## Using Python Stubs
The stubs are generated for the default `grpcio` python package, and the examples are using `asyncio`.
### Creating a Channel
In python, the default authority of the channel needs to be overridden, as it defaults to a string containing the port number. This will not work with the API, so we set the DNS name manually:
```python
channel = grpc.aio.secure_channel(
target='api.speechly.com:443',
credentials=grpc.ssl_channel_credentials(),
options=[('grpc.default_authority', 'api.speechly.com')]
)
```
### IdentityAPI
Login with `speechly.identity.v2.IdentityAPI` using an `app_id`:
```python
async def login(channel, device_id, app_id=None, project_id=None):
assert device_id, 'UUID device_is required'
assert (app_id or project_id), 'app_id or project_id is required'
identity_api = IdentityAPIStub(channel)
req = LoginRequest(device_id=device_id)
if app_id:
# if a token with a single app_id is required:
req.application.app_id = app_id
else:
# get a token that is usable for all apps in project:
req.project.project_id = project_id
response = await identity_api.Login(req)
token = response.token
expires = datetime.fromisoformat(response.expires_at)
return token, expires
```
### SLU
Open a bidirectional stream to `speechly.slu.v1.SLU/Stream` and send audio from a source generator to the API. The following example assumes that the `audio_stream` is an iterator that yields audio with 1 channel and sample rate 16KHz, in bytes chunks:
```python
async def stream_speech(channel, token, audio_stream, app_id=None):
auth = ('authorization', f'Bearer {token}')
async def read_responses(stream):
transcript = []
intent = ''
entities = []
resp = await stream.read()
while resp != grpc.aio.EOF:
if resp.HasField('started'):
print(f'audioContext {resp.audio_context} started')
elif resp.HasField('transcript'):
transcript.append(resp.transcript.word)
elif resp.HasField('entity'):
entities.append(resp.entity.entity)
elif resp.HasField('intent'):
intent = resp.intent.intent
elif resp.HasField('finished'):
print(f'audioContext {resp.audio_context} finished')
resp = await stream.read()
return intent, entities, transcript
async def send_audio(stream, source):
await stream.write(SLURequest(event=SLUEvent(event='START', app_id=app_id)))
for chunk in source:
await stream.write(SLURequest(audio=chunk))
await stream.write(SLURequest(event=SLUEvent(event='STOP')))
await stream.done_writing()
async with channel:
slu = SLUStub(channel)
try:
stream = slu.Stream(metadata=[auth])
config = SLUConfig(channels=1, sample_rate_hertz=16000)
await stream.write(SLURequest(config=config))
recv = read_responses(stream)
send = send_audio(stream, audio_stream)
r = await asyncio.gather(recv, send)
intent, entities, transcript = r[0]
print('Intent:', intent)
print('Entities:', ', '.join(entities))
print('Transcript:', ' '.join(transcript))
except grpc.aio.AioRpcError as e:
print('Error in SLU', str(e.code()), e.details())
```
# Using the HTTP REST API
The gRPC API is available also as JSON-based HTTP version. The following is an example of calling the `BatchAPI` with python `requests` library:
```python
import requests
import uuid
import base64
import time
# read an audio file in memory (note that the it should be PCM 16Khz 1 channels to get good results)
with open('test1_en.wav', 'rb') as f:
audio_data = f.read()
# create a device ID (uuid)
deviceId = uuid.uuid4()
# get a Speechly access token to use the correct Speechly app
r = requests.post(
'https://api.speechly.com/speechly.identity.v2.IdentityAPI/Login',
json={'deviceId': str(deviceId), 'application': {'appId': 'YOUR_APP_ID'}}
)
token = r.json()['token']
# send the file to the BatchAPI to create a batch transcribe operation
batch_req = [{
'config': {
'encoding': 1,
'channels': 1,
'sampleRateHertz': 16000
},
'audio': base64.b64encode(audio_data).decode('ascii')
}]
r = requests.post(
'https://api.speechly.com/speechly.slu.v1.BatchAPI/ProcessAudio',
headers={'authorization':f'Bearer {token}'},
json=batch_req
)
op = r.json()['operation']
# poll the BatchAPI, waiting for the batch operation to be done
while op['status'] != 'STATUS_DONE':
time.sleep(1)
r = requests.post(
'https://api.speechly.com/speechly.slu.v1.BatchAPI/QueryStatus',
headers={'authorization':f'Bearer {token}'},
json={'id': op['id']}
)
op = r.json()['operation']
if op['error'] != '':
raise Exception('error in transcribe: ' + op['error'])
# collect the words from the transcripts
transcript = [w['word'] for w in op['transcripts']]
print(' '.join(transcript))
```
Raw data
{
"_id": null,
"home_page": "https://github.com/speechly/api/tree/master/python",
"name": "speechly-api",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": "",
"keywords": "speech,asr,language,nlp",
"author": "Speechly",
"author_email": "",
"download_url": "https://files.pythonhosted.org/packages/eb/6b/a708deabb072ea06ebbba9cd529f58539f7e3abd8b69cb6ba48b9ca631a8/speechly_api-0.10.3.tar.gz",
"platform": null,
"description": "# Python Speechly API\n\nSee the generic [Speechly gRPC stubs documentation](https://github.com/speechly/api) for more information about using the API.\n\nA complete example on how to stream audio from a file to the Speechly API can be found in [speechly_grpc_example.py](https://github.com/speechly/api/blob/master/python/speechly_grpc_example.py).\n\n## Install\n\nInstall the latest package using `pip`:\n\n pip install speechly-api\n\nNote that the minimum python version supported is 3.6.\n\n## Using Python Stubs\n\nThe stubs are generated for the default `grpcio` python package, and the examples are using `asyncio`.\n\n### Creating a Channel\n\nIn python, the default authority of the channel needs to be overridden, as it defaults to a string containing the port number. This will not work with the API, so we set the DNS name manually:\n\n```python\nchannel = grpc.aio.secure_channel(\n target='api.speechly.com:443',\n credentials=grpc.ssl_channel_credentials(),\n options=[('grpc.default_authority', 'api.speechly.com')]\n)\n```\n\n### IdentityAPI\n\nLogin with `speechly.identity.v2.IdentityAPI` using an `app_id`:\n\n```python\nasync def login(channel, device_id, app_id=None, project_id=None):\n assert device_id, 'UUID device_is required'\n assert (app_id or project_id), 'app_id or project_id is required'\n identity_api = IdentityAPIStub(channel)\n req = LoginRequest(device_id=device_id)\n if app_id:\n # if a token with a single app_id is required:\n req.application.app_id = app_id\n else:\n # get a token that is usable for all apps in project:\n req.project.project_id = project_id\n response = await identity_api.Login(req)\n token = response.token\n expires = datetime.fromisoformat(response.expires_at)\n return token, expires\n```\n\n### SLU\n\nOpen a bidirectional stream to `speechly.slu.v1.SLU/Stream` and send audio from a source generator to the API. The following example assumes that the `audio_stream` is an iterator that yields audio with 1 channel and sample rate 16KHz, in bytes chunks:\n\n```python\nasync def stream_speech(channel, token, audio_stream, app_id=None):\n auth = ('authorization', f'Bearer {token}')\n\n async def read_responses(stream):\n transcript = []\n intent = ''\n entities = []\n resp = await stream.read()\n while resp != grpc.aio.EOF:\n if resp.HasField('started'):\n print(f'audioContext {resp.audio_context} started')\n elif resp.HasField('transcript'):\n transcript.append(resp.transcript.word)\n elif resp.HasField('entity'):\n entities.append(resp.entity.entity)\n elif resp.HasField('intent'):\n intent = resp.intent.intent\n elif resp.HasField('finished'):\n print(f'audioContext {resp.audio_context} finished')\n resp = await stream.read()\n return intent, entities, transcript\n\n async def send_audio(stream, source):\n await stream.write(SLURequest(event=SLUEvent(event='START', app_id=app_id)))\n for chunk in source:\n await stream.write(SLURequest(audio=chunk))\n await stream.write(SLURequest(event=SLUEvent(event='STOP')))\n await stream.done_writing()\n\n async with channel:\n slu = SLUStub(channel)\n try:\n stream = slu.Stream(metadata=[auth])\n config = SLUConfig(channels=1, sample_rate_hertz=16000)\n await stream.write(SLURequest(config=config))\n recv = read_responses(stream)\n send = send_audio(stream, audio_stream)\n r = await asyncio.gather(recv, send)\n intent, entities, transcript = r[0]\n print('Intent:', intent)\n print('Entities:', ', '.join(entities))\n print('Transcript:', ' '.join(transcript))\n except grpc.aio.AioRpcError as e:\n print('Error in SLU', str(e.code()), e.details())\n```\n\n# Using the HTTP REST API\n\nThe gRPC API is available also as JSON-based HTTP version. The following is an example of calling the `BatchAPI` with python `requests` library:\n\n\n```python\nimport requests\nimport uuid\nimport base64\nimport time\n\n# read an audio file in memory (note that the it should be PCM 16Khz 1 channels to get good results)\nwith open('test1_en.wav', 'rb') as f:\n audio_data = f.read()\n\n# create a device ID (uuid)\ndeviceId = uuid.uuid4()\n\n# get a Speechly access token to use the correct Speechly app\nr = requests.post(\n 'https://api.speechly.com/speechly.identity.v2.IdentityAPI/Login',\n json={'deviceId': str(deviceId), 'application': {'appId': 'YOUR_APP_ID'}}\n)\ntoken = r.json()['token']\n\n# send the file to the BatchAPI to create a batch transcribe operation\nbatch_req = [{\n 'config': {\n 'encoding': 1,\n 'channels': 1,\n 'sampleRateHertz': 16000\n },\n 'audio': base64.b64encode(audio_data).decode('ascii')\n}]\nr = requests.post(\n 'https://api.speechly.com/speechly.slu.v1.BatchAPI/ProcessAudio',\n headers={'authorization':f'Bearer {token}'},\n json=batch_req\n)\nop = r.json()['operation']\n\n# poll the BatchAPI, waiting for the batch operation to be done\nwhile op['status'] != 'STATUS_DONE':\n time.sleep(1)\n r = requests.post(\n 'https://api.speechly.com/speechly.slu.v1.BatchAPI/QueryStatus',\n headers={'authorization':f'Bearer {token}'},\n json={'id': op['id']}\n )\n op = r.json()['operation']\n if op['error'] != '':\n raise Exception('error in transcribe: ' + op['error'])\n\n# collect the words from the transcripts\ntranscript = [w['word'] for w in op['transcripts']]\nprint(' '.join(transcript))\n```\n",
"bugtrack_url": null,
"license": "",
"summary": "Speechly Public Protobuf Stubs",
"version": "0.10.3",
"project_urls": {
"Homepage": "https://github.com/speechly/api/tree/master/python",
"Source": "https://github.com/speechly/api",
"Speechly": "https://www.speechly.com/"
},
"split_keywords": [
"speech",
"asr",
"language",
"nlp"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "bbc90e5514f89df5b4bfa9f01d458c7f2def3351b49b758f49ce714128249720",
"md5": "eef177699d544014387070ab0b0d2256",
"sha256": "a9e01ef2546e1570302644682fc1a61fbd3a5cec4c8970672f9b7e9a370720d4"
},
"downloads": -1,
"filename": "speechly_api-0.10.3-py3-none-any.whl",
"has_sig": false,
"md5_digest": "eef177699d544014387070ab0b0d2256",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8",
"size": 84729,
"upload_time": "2023-08-31T07:39:16",
"upload_time_iso_8601": "2023-08-31T07:39:16.482032Z",
"url": "https://files.pythonhosted.org/packages/bb/c9/0e5514f89df5b4bfa9f01d458c7f2def3351b49b758f49ce714128249720/speechly_api-0.10.3-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "eb6ba708deabb072ea06ebbba9cd529f58539f7e3abd8b69cb6ba48b9ca631a8",
"md5": "be08afb6a11f97249089b391fdd1ae21",
"sha256": "1a4cd7703f14d43d4f951ef2055192c98f3e0bf7d169d1f6e012aba5b078ae57"
},
"downloads": -1,
"filename": "speechly_api-0.10.3.tar.gz",
"has_sig": false,
"md5_digest": "be08afb6a11f97249089b391fdd1ae21",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 50370,
"upload_time": "2023-08-31T07:39:18",
"upload_time_iso_8601": "2023-08-31T07:39:18.468822Z",
"url": "https://files.pythonhosted.org/packages/eb/6b/a708deabb072ea06ebbba9cd529f58539f7e3abd8b69cb6ba48b9ca631a8/speechly_api-0.10.3.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-08-31 07:39:18",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "speechly",
"github_project": "api",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "speechly-api"
}