# Python Houndify SDK
The Houndify Python SDK allows you to make streaming voice and text queries to the Houndify API from your Python project. The SDK provides two classes **TextHoundClient** and **StreamingHoundClient** for making text and voice queries to the Houndify API. See the *Usage* section below as well as sample scripts in the SDK for more information.
## Sample Scripts
The Python SDK ships with sample scripts that demonstrate how to use various features. Before you use the SDK, you need a valid Client ID and Client Key. You can get these keys from [Houndify.com](https://www.houndify.com) by registering a new client, and enabling domains.
### Sending Text Queries
For an example of a text client take a look at the sample project *sample_text.py*. It lets you pass in a text query and returns a [JSON Response](https://docs.houndify.com/reference/HoundServer).
```bash
./sample_text.py -id <CLIENT ID> -key <CLIENT KEY> '<QUERY>'
```
### Sending Audio Queries
You can send streaming audio to the sample program *sample_wave.py*. There are two `.wav` files you can try. You will get back a [JSON Response](https://docs.houndify.com/reference/HoundServer) based on the contents of the audio.
```bash
./sample_wave.py -id <CLIENT ID> -key <CLIENT KEY> test_audio/what_is_the_weather_like_in_toronto.wav
```
There is another sample program *sample_stdin.py* which will take PCM samples from `stdin`. You can use it with arecord/sox to do real-time decoding from a microphone.
```bash
arecord -t raw -c 1 -r 16000 -f S16_LE | ./sample_stdin.py <CLIENT ID> <CLIENT KEY>
```
```bash
rec -pq | sox - -c 1 -r 16000 -t s16 -L - | ./sample_stdin.py <CLIENT ID> <CLIENT KEY>
```
### Sending either
`query_houndify.py` contains similar functionality to `sample_wave.py` and `sample_text.py`. Additionally, it provides the following options for setting endpoints and making testing easier.
```
--endpoint ENDPOINT, -e ENDPOINT
change endpoint the SDK will hit to query Houndify.
text-query default: https://api.houndify.com/v1/text
audio-file default: https://api.houndify.com/v1/audio
--request-info-file REQUEST_INFO_FILE, -r REQUEST_INFO_FILE
Path to JSON file with Houndify request info options.
--expected-transcript EXPECTED_TRANSCRIPT, -x EXPECTED_TRANSCRIPT
The expected transcript from the audio file. If this
argument is provided the script will compare it to the
transcript from the Houndify. On failure, the
script will return 1
--silent, -s The script will not print the server's JSON response
```
* `endpoint` Can be used on self hosted solutions
* `expected-transcript` is useful when testing Houndify capabilities
* `silent` is often used with `expected-transcript` to make the output less verbose
## Usage
The main module in the SDK is *houndify.py*, which contains three classes:
* **TextHoundClient**
* **StreamingHoundClient**
* **HoundListener**
### Text Queries: TextHoundClient
This class is used for making text queries to the Houndify API. The constructor expects:
* `clientID`: This is the Client ID of your Houndify app.
* `clientKey`: This is the Client Key of your Houndify app.
* `userID`: This parameter should be unique for every user that uses your app.
* `requestInfo`: (optional) This should be a dictionary that will make the JSON response more accurate. See [RequestInfo](https://docs.houndify.com/reference/RequestInfo) for supported keys.
* `proxyHost`: (optional) Pass the host for HTTP Connect Tunnelling to make queries through proxy.
* `proxyPort`: (optional) Port for HTTP Connect Tunnelling.
* `proxyHeaders`: (optional) Extra headers for HTTP Connect Tunnelling.
* `endpoint`: (optional) Change the backend endpoint the SDK will hit for queries
```python
import houndify
clientId = "YOUR_CLIENT_ID"
clientKey = "YOUR_CLIENT_KEY"
userId = "test_user"
requestInfo = {
"Latitude": 37.388309,
"Longitude": -121.973968
}
client = houndify.TextHoundClient(clientId, clientKey, userId, requestInfo)
```
The method that is used for sending a text query is **TextHoundClient.query(query_string)** and it returns a dictionary with [response JSON](https://docs.houndify.com/reference/HoundServer) in it.
```python
response = client.query("What is the weather like today?")
```
You can reset [RequestInfo fields](https://docs.houndify.com/reference/RequestInfo) via the **TextHoundClient.setHoundRequestInfo(key, value)** and **TextHoundClient.removeHoundRequestInfo(key)** methods.
```python
client.setHoundRequestInfo("City", "Santa Clara")
client.removeHoundRequestInfo("City")
```
### Audio Queries: StreamingHoundClient
In order to send an audio query to the Houndify API you need to initialize a **StreamingHoundClient**. The constructor expects the following arguments:
* `clientID`: This is the Client ID of your Houndify app.
* `clientKey`: This is the Client Key of your Houndify app.
* `userID`: This parameter should be unique for every user that uses your app.
* `requestInfo`: (optional) This should be a dictionary that will make the JSON response more accurate. See [RequestInfo](https://docs.houndify.com/reference/RequestInfo) for supported keys.
* `sampleRate`: (optional) The sample rate of the audio, either 8000 or 16000 Hz. It will default to 16000 if not supplied.
* `enableVAD`: (optional) Boolean specifying whether you want to support Voice Activity Detection. If True *fill()* method will return True and ignore any more audio bytes after server detects silence. The default value is False.
* `useSpeex`: (optional) This flag enables Speex conversion of audio. The default value is False. See *Speex Compression* section below for instruction on setting Speex up.
* `proxyHost`: (optional) Pass host for HTTP Connect Tunnelling to make queries through proxy.
* `proxyPort`: (optional) Port for HTTP Connect Tunnelling.
* `proxyHeaders`: (optional) Extra headers for HTTP Connect Tunnelling.
* `endpoint`: (optional) Change the backend endpoint the SDK will hit for queries
```python
import houndify
clientId = "YOUR_CLIENT_ID"
clientKey = "YOUR_CLIENT_KEY"
userId = "test_user"
client = houndify.StreamingHoundClient(clientId, clientKey, userId, sampleRate=8000)
```
Additionally you'll need to extend and create **HoundListener**:
```python
class MyListener(houndify.HoundListener):
def onPartialTranscript(self, transcript):
"""
onPartialTranscript is fired when the server has sent a partial transcript
in live transcription mode. "transcript" is a string with the partial transcript.
"""
def onPartialTranscriptRaw(self, response):
"""
onPartialTranscriptRaw is fired when the server has a partial transcript.
This method gives access to the full Houndify response.
"""
def onFinalPartialTranscript(self, transcript):
"""
onFinalPartialTranscript is fired once the server has identified one or more
complete sentences that are guaranteed not to change in the future.
These sentences won't be included in partial transcripts going forward,
the client needs to accumulate them in order to compile the full transcript.
Only occurs in live transcription mode.
"""
def onPartialTranscriptProperties(self, transcript, props):
"""
onPartialTranscriptProperties is fired when the server has a partial transcript
and detailed information is provided by the server (usually in live transcription
mode). "props" is a HoundTranscriptProperties JSON object (as a Python dict)
containing the "Tokens" array and optional extra fields such as "TopicIdentification"
or "EntityDetection".
"""
def onFinalPartialTranscriptProperties(self, transcript, props):
"""
onFinalPartialTranscriptProperties is fired once the server has identified one
or more complete sentences that are guaranteed not to change in the future.
These sentences won't be included in partial transcripts going forward,
the client needs to accumulate them in order to compile the full transcript.
"props" is a HoundTranscriptProperties JSON object (as a Python dict)
containing the "Tokens" array and optional extra fields such as "TopicIdentification"
or "EntityDetection". Only occurs in live transcription mode.
"""
def onFinalResponse(self, response):
"""
onFinalResponse is fired when the server has completed processing the query
and has a response. "response" is the JSON object (as a Python dict) which
the server sends back.
"""
def onError(self, err):
"""
onError is fired if there is an error interacting with the server. It contains
the parsed JSON from the server.
"""
```
### Audio Queries: Code Example
Finally, you should start a request with passing an instance of your Listener to **StreamingHoundClient.start(listener, isSpeexFile=False)**, pipe the audio through **StreamingHoundClient.fill(samples)** and call **StreamingHoundClient.finish()** when the request is done.
*Note: StreamingHoundClient supports 8/16 kHz mono 16-bit little-endian PCM samples.*
```python
class MyListener(houndify.HoundListener):
def onPartialTranscript(self, transcript):
print("Partial transcript: " + transcript)
def onFinalResponse(self, response):
print("Final response: " + str(response))
def onError(self, err):
print("Error " + str(err))
client.start(MyListener())
# 'samples' is the list of mono 16-bit little-endian PCM samples
client.fill(samples)
result = client.finish() # result is either final response or error
```
There are four more useful methods in **StreamingHoundClient** for resetting sample rate, location and request info fields.
```python
client.setSampleRate(8000) #or 16000
client.setLocation(37.388309, -121.973968)
client.setHoundRequestInfo("City", "Santa Clara")
client.removeHoundRequestInfo("City")
```
### Conversation State
Houndify domains can use context to enable a conversational user interaction. For example, users can say "show me coffee shops near me", "which ones have wifi?", "sort by rating", "navigate to the first one". Both **TextHoundClient** and **StreamingHoundClient** have **setConversationState(state)** method that you can use to set [Conversation State](https://docs.houndify.com/reference/CommandResult#field_ConversationState) extracted from a previous response.
```python
client = houndify.TextHoundClient(clientId, clientKey, userId)
response = client.query("What is the weather like in Toronto?")
conversationState = response["AllResults"][0]["ConversationState"]
client.setConversationState(conversationState)
response = client.query("What about Santa Clara?")
```
## Speex Compression
You can use *pySHSpeex* module included in the SDK for sending compressed audio. To build and install *pySHSpeex* run following commands:
```bash
# setup script requires Python development headers:
# sudo apt-get install python-dev
# yum install python-devel
cd pySHSpeex
sudo python setup.py install
```
*Note: this will install pySHSpeex system-wide although it is possible to install it per-user following standard Python module installation procedure.*
You have to pass the additional **useSpeex=True** flag to the StreamingHoundClient in order to enable compression.
```python
import houndify
clientId = "YOUR_CLIENT_ID"
clientKey = "YOUR_CLIENT_KEY"
userId = "test_user"
client = houndify.StreamingHoundClient(clientId, clientKey, userId, useSpeex=True)
```
Raw data
{
"_id": null,
"home_page": "https://www.houndify.com/sdks#python",
"name": "Houndify",
"maintainer": "Soundhound Inc.",
"docs_url": null,
"requires_python": null,
"maintainer_email": null,
"keywords": "houndify",
"author": "Soundhound Inc.",
"author_email": "pypi-maintainer@soundhound.com",
"download_url": "https://files.pythonhosted.org/packages/81/38/63348ec5354e1f7cd0210db2620baa499d05da2eea0053b99e3533b26ed7/Houndify-2.1.3.tar.gz",
"platform": null,
"description": "# Python Houndify SDK\n\nThe Houndify Python SDK allows you to make streaming voice and text queries to the Houndify API from your Python project. The SDK provides two classes **TextHoundClient** and **StreamingHoundClient** for making text and voice queries to the Houndify API. See the *Usage* section below as well as sample scripts in the SDK for more information.\n\n## Sample Scripts\n\nThe Python SDK ships with sample scripts that demonstrate how to use various features. Before you use the SDK, you need a valid Client ID and Client Key. You can get these keys from [Houndify.com](https://www.houndify.com) by registering a new client, and enabling domains.\n\n### Sending Text Queries\n\nFor an example of a text client take a look at the sample project *sample_text.py*. It lets you pass in a text query and returns a [JSON Response](https://docs.houndify.com/reference/HoundServer).\n\n```bash\n./sample_text.py -id <CLIENT ID> -key <CLIENT KEY> '<QUERY>'\n```\n\n### Sending Audio Queries\n\nYou can send streaming audio to the sample program *sample_wave.py*. There are two `.wav` files you can try. You will get back a [JSON Response](https://docs.houndify.com/reference/HoundServer) based on the contents of the audio.\n\n```bash\n./sample_wave.py -id <CLIENT ID> -key <CLIENT KEY> test_audio/what_is_the_weather_like_in_toronto.wav\n```\n\nThere is another sample program *sample_stdin.py* which will take PCM samples from `stdin`. You can use it with arecord/sox to do real-time decoding from a microphone.\n\n```bash\narecord -t raw -c 1 -r 16000 -f S16_LE | ./sample_stdin.py <CLIENT ID> <CLIENT KEY>\n```\n```bash\nrec -pq | sox - -c 1 -r 16000 -t s16 -L - | ./sample_stdin.py <CLIENT ID> <CLIENT KEY>\n```\n\n### Sending either\n\n`query_houndify.py` contains similar functionality to `sample_wave.py` and `sample_text.py`. Additionally, it provides the following options for setting endpoints and making testing easier.\n\n```\n--endpoint ENDPOINT, -e ENDPOINT\n change endpoint the SDK will hit to query Houndify.\n text-query default: https://api.houndify.com/v1/text\n audio-file default: https://api.houndify.com/v1/audio\n--request-info-file REQUEST_INFO_FILE, -r REQUEST_INFO_FILE\n Path to JSON file with Houndify request info options.\n--expected-transcript EXPECTED_TRANSCRIPT, -x EXPECTED_TRANSCRIPT\n The expected transcript from the audio file. If this\n argument is provided the script will compare it to the\n transcript from the Houndify. On failure, the\n script will return 1\n--silent, -s The script will not print the server's JSON response\n```\n\n* `endpoint` Can be used on self hosted solutions\n* `expected-transcript` is useful when testing Houndify capabilities\n* `silent` is often used with `expected-transcript` to make the output less verbose\n\n\n## Usage\n\nThe main module in the SDK is *houndify.py*, which contains three classes:\n\n* **TextHoundClient**\n* **StreamingHoundClient**\n* **HoundListener**\n\n\n### Text Queries: TextHoundClient\n\nThis class is used for making text queries to the Houndify API. The constructor expects:\n\n* `clientID`: This is the Client ID of your Houndify app.\n* `clientKey`: This is the Client Key of your Houndify app.\n* `userID`: This parameter should be unique for every user that uses your app.\n* `requestInfo`: (optional) This should be a dictionary that will make the JSON response more accurate. See [RequestInfo](https://docs.houndify.com/reference/RequestInfo) for supported keys.\n* `proxyHost`: (optional) Pass the host for HTTP Connect Tunnelling to make queries through proxy.\n* `proxyPort`: (optional) Port for HTTP Connect Tunnelling.\n* `proxyHeaders`: (optional) Extra headers for HTTP Connect Tunnelling.\n* `endpoint`: (optional) Change the backend endpoint the SDK will hit for queries\n\n```python\nimport houndify\n\nclientId = \"YOUR_CLIENT_ID\"\nclientKey = \"YOUR_CLIENT_KEY\"\nuserId = \"test_user\"\nrequestInfo = {\n \"Latitude\": 37.388309,\n \"Longitude\": -121.973968\n}\n\nclient = houndify.TextHoundClient(clientId, clientKey, userId, requestInfo)\n```\n\nThe method that is used for sending a text query is **TextHoundClient.query(query_string)** and it returns a dictionary with [response JSON](https://docs.houndify.com/reference/HoundServer) in it.\n\n```python\nresponse = client.query(\"What is the weather like today?\")\n```\n\nYou can reset [RequestInfo fields](https://docs.houndify.com/reference/RequestInfo) via the **TextHoundClient.setHoundRequestInfo(key, value)** and **TextHoundClient.removeHoundRequestInfo(key)** methods.\n\n```python\nclient.setHoundRequestInfo(\"City\", \"Santa Clara\")\nclient.removeHoundRequestInfo(\"City\")\n```\n\n\n### Audio Queries: StreamingHoundClient\n\nIn order to send an audio query to the Houndify API you need to initialize a **StreamingHoundClient**. The constructor expects the following arguments:\n\n* `clientID`: This is the Client ID of your Houndify app.\n* `clientKey`: This is the Client Key of your Houndify app.\n* `userID`: This parameter should be unique for every user that uses your app.\n* `requestInfo`: (optional) This should be a dictionary that will make the JSON response more accurate. See [RequestInfo](https://docs.houndify.com/reference/RequestInfo) for supported keys.\n* `sampleRate`: (optional) The sample rate of the audio, either 8000 or 16000 Hz. It will default to 16000 if not supplied.\n* `enableVAD`: (optional) Boolean specifying whether you want to support Voice Activity Detection. If True *fill()* method will return True and ignore any more audio bytes after server detects silence. The default value is False.\n* `useSpeex`: (optional) This flag enables Speex conversion of audio. The default value is False. See *Speex Compression* section below for instruction on setting Speex up.\n* `proxyHost`: (optional) Pass host for HTTP Connect Tunnelling to make queries through proxy.\n* `proxyPort`: (optional) Port for HTTP Connect Tunnelling.\n* `proxyHeaders`: (optional) Extra headers for HTTP Connect Tunnelling.\n* `endpoint`: (optional) Change the backend endpoint the SDK will hit for queries\n\n```python\nimport houndify\n\nclientId = \"YOUR_CLIENT_ID\"\nclientKey = \"YOUR_CLIENT_KEY\"\nuserId = \"test_user\"\nclient = houndify.StreamingHoundClient(clientId, clientKey, userId, sampleRate=8000)\n```\n\nAdditionally you'll need to extend and create **HoundListener**:\n\n```python\nclass MyListener(houndify.HoundListener):\n def onPartialTranscript(self, transcript):\n \"\"\"\n onPartialTranscript is fired when the server has sent a partial transcript\n in live transcription mode. \"transcript\" is a string with the partial transcript.\n \"\"\"\n def onPartialTranscriptRaw(self, response):\n \"\"\"\n onPartialTranscriptRaw is fired when the server has a partial transcript.\n This method gives access to the full Houndify response.\n \"\"\"\n def onFinalPartialTranscript(self, transcript):\n \"\"\"\n onFinalPartialTranscript is fired once the server has identified one or more\n complete sentences that are guaranteed not to change in the future.\n These sentences won't be included in partial transcripts going forward,\n the client needs to accumulate them in order to compile the full transcript.\n Only occurs in live transcription mode.\n \"\"\"\n def onPartialTranscriptProperties(self, transcript, props):\n \"\"\"\n onPartialTranscriptProperties is fired when the server has a partial transcript\n and detailed information is provided by the server (usually in live transcription\n mode). \"props\" is a HoundTranscriptProperties JSON object (as a Python dict)\n containing the \"Tokens\" array and optional extra fields such as \"TopicIdentification\"\n or \"EntityDetection\".\n \"\"\"\n def onFinalPartialTranscriptProperties(self, transcript, props):\n \"\"\"\n onFinalPartialTranscriptProperties is fired once the server has identified one\n or more complete sentences that are guaranteed not to change in the future.\n These sentences won't be included in partial transcripts going forward,\n the client needs to accumulate them in order to compile the full transcript.\n \"props\" is a HoundTranscriptProperties JSON object (as a Python dict)\n containing the \"Tokens\" array and optional extra fields such as \"TopicIdentification\"\n or \"EntityDetection\". Only occurs in live transcription mode.\n \"\"\"\n def onFinalResponse(self, response):\n \"\"\"\n onFinalResponse is fired when the server has completed processing the query\n and has a response. \"response\" is the JSON object (as a Python dict) which\n the server sends back.\n \"\"\"\n def onError(self, err):\n \"\"\"\n onError is fired if there is an error interacting with the server. It contains\n the parsed JSON from the server.\n \"\"\"\n\n```\n\n\n### Audio Queries: Code Example\n\nFinally, you should start a request with passing an instance of your Listener to **StreamingHoundClient.start(listener, isSpeexFile=False)**, pipe the audio through **StreamingHoundClient.fill(samples)** and call **StreamingHoundClient.finish()** when the request is done.\n\n*Note: StreamingHoundClient supports 8/16 kHz mono 16-bit little-endian PCM samples.*\n\n```python\nclass MyListener(houndify.HoundListener):\n def onPartialTranscript(self, transcript):\n print(\"Partial transcript: \" + transcript)\n\n def onFinalResponse(self, response):\n print(\"Final response: \" + str(response))\n\n def onError(self, err):\n print(\"Error \" + str(err))\n\n\nclient.start(MyListener())\n# 'samples' is the list of mono 16-bit little-endian PCM samples\nclient.fill(samples)\nresult = client.finish() # result is either final response or error\n```\n\nThere are four more useful methods in **StreamingHoundClient** for resetting sample rate, location and request info fields.\n\n```python\nclient.setSampleRate(8000) #or 16000\nclient.setLocation(37.388309, -121.973968)\nclient.setHoundRequestInfo(\"City\", \"Santa Clara\")\nclient.removeHoundRequestInfo(\"City\")\n```\n\n\n### Conversation State\n\nHoundify domains can use context to enable a conversational user interaction. For example, users can say \"show me coffee shops near me\", \"which ones have wifi?\", \"sort by rating\", \"navigate to the first one\". Both **TextHoundClient** and **StreamingHoundClient** have **setConversationState(state)** method that you can use to set [Conversation State](https://docs.houndify.com/reference/CommandResult#field_ConversationState) extracted from a previous response.\n\n```python\nclient = houndify.TextHoundClient(clientId, clientKey, userId)\n\nresponse = client.query(\"What is the weather like in Toronto?\")\n\nconversationState = response[\"AllResults\"][0][\"ConversationState\"]\nclient.setConversationState(conversationState)\n\nresponse = client.query(\"What about Santa Clara?\")\n```\n\n\n\n## Speex Compression\n\nYou can use *pySHSpeex* module included in the SDK for sending compressed audio. To build and install *pySHSpeex* run following commands:\n\n```bash\n# setup script requires Python development headers:\n# sudo apt-get install python-dev\n# yum install python-devel\n\ncd pySHSpeex\nsudo python setup.py install\n```\n*Note: this will install pySHSpeex system-wide although it is possible to install it per-user following standard Python module installation procedure.*\n\nYou have to pass the additional **useSpeex=True** flag to the StreamingHoundClient in order to enable compression.\n\n```python\nimport houndify\n\nclientId = \"YOUR_CLIENT_ID\"\nclientKey = \"YOUR_CLIENT_KEY\"\nuserId = \"test_user\"\nclient = houndify.StreamingHoundClient(clientId, clientKey, userId, useSpeex=True)\n```",
"bugtrack_url": null,
"license": "MIT",
"summary": "Houndify libraries and SoundHound speex encoder",
"version": "2.1.3",
"project_urls": {
"Homepage": "https://www.houndify.com/sdks#python"
},
"split_keywords": [
"houndify"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "813863348ec5354e1f7cd0210db2620baa499d05da2eea0053b99e3533b26ed7",
"md5": "f35704f18990282ecbd85eeed8b8d691",
"sha256": "8312aafe1d65d0ce624e38f1fabed44b0b2b9abbe0ba31a7211d11623e76dcc5"
},
"downloads": -1,
"filename": "Houndify-2.1.3.tar.gz",
"has_sig": false,
"md5_digest": "f35704f18990282ecbd85eeed8b8d691",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 194855,
"upload_time": "2024-10-03T15:56:08",
"upload_time_iso_8601": "2024-10-03T15:56:08.181990Z",
"url": "https://files.pythonhosted.org/packages/81/38/63348ec5354e1f7cd0210db2620baa499d05da2eea0053b99e3533b26ed7/Houndify-2.1.3.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-10-03 15:56:08",
"github": false,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"lcname": "houndify"
}