Sample DTMF recognizer client
Nuance Mix offers a simple Python client application that you may download and use for DTMF recognition using the DTMF Recognizer gRPC API.
Prerequisites
To run this client, you need:
- Python 3.6 or later.
- The generated Python stub files from gRPC setup.
- Your client ID and secret from Prerequisites from Mix.
- Download and extract the DTMF sample files: /downloads/nrc-grpc/v1/sample-nr-dtmf-client.zip.
Build the app
Download the zip file and extract its files into the same directory as the nuance directory, which contains your proto files and Python stubs.
The files are:
- nr-dtmf-client.py: Sample python client.
- run-nr-dtmf-client.sh: Convenience script to acquire a token and run the sample client.
- generate-protobuf-and-grpc-python.sh: Convenience script to generate the python stubs from the proto file.
- dtmf_months.grxml: Example GRXML grammar, could be loaded as a URI grammar if hosted on a web server.
- README.txt: Brief information on how to run the sample client.
- nuance/nrc/v1/nrc.proto: The gRPC proto file for the Nuance Mix service.
Note:
The sample app contains a copy of the proto files. If you already have the proto file in your directory, you can overwrite the existing file.Run the app
Use this command to generate an access token and run the app, where 01234.ulaw is the relative or absolute path to the audio file:
./run-python-client.sh 01234.ulaw
The token authorizes the application to call the NRaaS service. It takes your credentials and stores the resulting token in an environment variable, MY_TOKEN.
Alternatively, you can include the token-generation code within the application, reading the credentials from a configuration file.
You can use this client to request DTMF recognition, optionally including recognition resources such as inline or URI DTMF grammars for specific DTMF sequences.
The script generate-protobuf-and-grpc-python.sh can be used to generate the Python stubs from the proto file. These are the resulting client files, above the nuance directory holding the proto file and its corresponding Python stubs:
├── README.txt
├── generate-protobuf-and-grpc-python.sh
├── run-nr-dtmf-client.sh
├── nr-dtmf-client.py
├── dtmf_months.grxml
└── nuance
└── nrc
└── v1
├── nrc.proto
├── nrc_pb2.py
└── nrc_pb2_grpc.py
You can use this client to request DTMF recognition, optionally including recognition resources such as inline or URI DTMF grammars for specific DTMF sequences.
Edit shell script
First, edit the shell script, run-nr-dtmf-client.sh, to add your credentials to generate an access token. The script generates a token that authorizes the client to call the Nuance Recognizer service. It takes your credentials and stores the resulting token in an environment variable, TOKEN.
#!/bin/bash
CLIENT_ID="<ENTER_YOUR_MIX_CLIENT_ID_HERE>"
SECRET="<ENTER_YOUR_MIX_CLIENT_SECRET_HERE>"
# URL encode the client id by converting ':' characters to '%3A'
CLIENT_ID=${CLIENT_ID//:/%3A}
AUTHURL="https://auth.crt.nuance.com/oauth2/token"
# Acquire token from server, extract token string from the json response.
export TOKEN="$(curl -s -u "$CLIENT_ID:$SECRET" "$AUTHURL" \
-d "grant_type=client_credentials" \
-d "scope=nr" \
| python -c 'import sys, json; print(json.load(sys.stdin)["access_token"])'
)"
# Run the client. Pass the token and DTMF sequence to recognize as command line arguments.
./nr-dtmf-client.py nr.api.nuance.com:443 $TOKEN $1
Alternatively, you might incorporate the token-generation code within the client, reading the credentials from a configuration file.
This client accepts arguments positionally, without names:
server_address = sys.argv[1]
access_token = sys.argv[2]
dtmf_sequence = sys.argv[3]
Pass these arguments as you run the client using the shell script:
-
- The URI of the Nuance Recognizer region and language group. For the United States region and North America language group: nr.api.nuance.com:443.
-
An access token generated by the Mix OAuth server, usually as an environment variable, in this example $TOKEN.
-
A string of the DTMF sequence to be recognized.
Run the recognition client
The client accepts a string specifying a sequence of DTMF digits. The client will send that sequence of DTMF digits to Nuance Recognizer to recognize them. The DTMFs are sent one at a time with some delay in between each to simulate a live DTMF entry.
Run the client from the shell script, passing it a DTMF sequence string. The client loads a builtin DTMF grammar and also an inline DTMF grammar that recognizes some interesting sequences. You can also specify these preset sequences: pi, e, phi, sqrt2.
Scenario 1: Recognize 1,2,3,4
This scenario recognizes the DTMF sequence 1 2 3 4:
$ ./run-nr-dtmf-client.sh 1234
Recognizing DTMF sequence: ['1', '2', '3', '4']
Sending recognition_init {
parameters {
no_input_timeout_ms: 6000
dtmf_interdigit_timeout_ms: 3000
dtmf_term_char: "#"
}
resources {
builtin: "builtin:dtmf/digits"
weight: 1
}
resources {
inline_grammar {
grammar: "<?xml version=\"1.0\" encoding=\"UTF-8\"?><grammar xml:lang=\"en-US\" mode=\"dtmf\" version=\"1.0\" tag-format=\"swi-semantics/1.0\" root=\"NUMBERS\" xmlns=\"http://www.w3.org/2001/06/grammar\"><rule id=\"NUMBERS\" scope=\"public\"><one-of><item><ruleref uri=\"#PI\" /><tag>MEANING=PI.SWI_literal.replace(/.*/, \'PI\')</tag></item><item><ruleref uri=\"#E\" /><tag>MEANING=E.SWI_literal.replace(/.*/, \'E\')</tag></item><item><ruleref uri=\"#PHI\" /><tag>MEANING=PHI.SWI_literal.replace(/.*/, \'PHI\')</tag></item><item><ruleref uri=\"#SQRT2\" /><tag>MEANING=SQRT2.SWI_literal.replace(/.*/, \'SQRT2\')</tag></item></one-of></rule><rule id=\"PI\"><item>3</item><item>*</item><item>1</item><item>4</item><item>1</item><item>5</item><item>9</item></rule><rule id=\"E\"><item>2</item><item>*</item><item>7</item><item>1</item><item>8</item><item>2</item><item>8</item></rule><rule id=\"PHI\"><item>1</item><item>*</item><item>6</item><item>1</item><item>8</item><item>0</item><item>3</item></rule><rule id=\"SQRT2\"><item>1</item><item>*</item><item>4</item><item>1</item><item>4</item><item>2</item><item>1</item></rule></grammar>"
}
weight: 2
}
}
DTMFRecognize() reponse --> status {
code: 200
message: "OK"
}
Sending DTMF 1
DTMFRecognize() reponse --> start_of_speech {
first_audio_to_start_of_speech_ms: 1000
}
Sending DTMF 2
Sending DTMF 3
Sending DTMF 4
DONE Sending DTMFs
DTMFRecognize() reponse --> result {
formatted_text: "<result><interpretation conf=\"1\"><text mode=\"dtmf\">1 2 3 4</text><instance grammar=\"builtin:dtmf/digits\"><SWI_meaning>1234</SWI_meaning><MEANING conf=\"1\">1234</MEANING><SWI_literal>1 2 3 4</SWI_literal><SWI_grammarName>builtin:dtmf/digits</SWI_grammarName></instance></interpretation></result>"
status: "SUCCESS"
}
In this example, the sequence was properly recognized and was matched by the builtin:dtmf/digits grammar.
<result>
<interpretation conf="1">
<text mode="dtmf">1 2 3 4</text>
<instance grammar="builtin:dtmf/digits">
<SWI_meaning>1234</SWI_meaning>
<MEANING conf="1">1234</MEANING>
<SWI_literal>1 2 3 4</SWI_literal>
<SWI_grammarName>builtin:dtmf/digits</SWI_grammarName>
</instance>
</interpretation>
</result>
Scenario 2: Recognize pi
This scenario recognizes pi, one of the client’s pre-set DTMF sequences:
$ ./run-nr-dtmf-client.sh pi
Recognizing DTMF sequence: ['3', '*', '1', '4', '1', '5', '9']
Sending recognition_init {
parameters {
no_input_timeout_ms: 6000
dtmf_interdigit_timeout_ms: 3000
dtmf_term_char: "#"
}
resources {
builtin: "builtin:dtmf/digits"
weight: 1
}
resources {
inline_grammar {
grammar: "<?xml version=\"1.0\" encoding=\"UTF-8\"?><grammar xml:lang=\"en-US\" mode=\"dtmf\" version=\"1.0\" tag-format=\"swi-semantics/1.0\" root=\"NUMBERS\" xmlns=\"http://www.w3.org/2001/06/grammar\"><rule id=\"NUMBERS\" scope=\"public\"><one-of><item><ruleref uri=\"#PI\" /><tag>MEANING=PI.SWI_literal.replace(/.*/, \'PI\')</tag></item><item><ruleref uri=\"#E\" /><tag>MEANING=E.SWI_literal.replace(/.*/, \'E\')</tag></item><item><ruleref uri=\"#PHI\" /><tag>MEANING=PHI.SWI_literal.replace(/.*/, \'PHI\')</tag></item><item><ruleref uri=\"#SQRT2\" /><tag>MEANING=SQRT2.SWI_literal.replace(/.*/, \'SQRT2\')</tag></item></one-of></rule><rule id=\"PI\"><item>3</item><item>*</item><item>1</item><item>4</item><item>1</item><item>5</item><item>9</item></rule><rule id=\"E\"><item>2</item><item>*</item><item>7</item><item>1</item><item>8</item><item>2</item><item>8</item></rule><rule id=\"PHI\"><item>1</item><item>*</item><item>6</item><item>1</item><item>8</item><item>0</item><item>3</item></rule><rule id=\"SQRT2\"><item>1</item><item>*</item><item>4</item><item>1</item><item>4</item><item>2</item><item>1</item></rule></grammar>"
}
weight: 2
}
}
DTMFRecognize() reponse --> status {
code: 200
message: "OK"
}
Sending DTMF 3
DTMFRecognize() reponse --> start_of_speech {
first_audio_to_start_of_speech_ms: 1000
}
Sending DTMF *
Sending DTMF 1
Sending DTMF 4
Sending DTMF 1
Sending DTMF 5
Sending DTMF 9
DONE Sending DTMFs
DTMFRecognize() reponse --> result {
formatted_text: "<result><interpretation conf=\"1\"><text mode=\"dtmf\">3 * 1 4 1 5 9</text><instance grammar=\"10171153428116319910\"><MEANING conf=\"1\">PI</MEANING><SWI_literal>3 * 1 4 1 5 9</SWI_literal><SWI_grammarName>10171153428116319910</SWI_grammarName><SWI_meaning>{MEANING:PI}</SWI_meaning></instance></interpretation></result>"
status: "SUCCESS"
}
In this example, the sequence was properly recognized and was matched by the inline grammar, which provided a meaning of “PI” to the recognized sequence.
<result>
<interpretation conf="1">
<text mode="dtmf">3 * 1 4 1 5 9</text>
<instance grammar="10171153428116319910">
<MEANING conf="1">PI</MEANING>
<SWI_literal>3 * 1 4 1 5 9</SWI_literal>
<SWI_grammarName>10171153428116319910</SWI_grammarName>
<SWI_meaning>{MEANING:PI}</SWI_meaning>
</instance>
</interpretation>
</result>
Feedback
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.