Sample Python runtime client

NLUaaS offers a fully-functional sample Python client application that you can download and use to interpret the meaning of text using the Runtime gRPC API. To run this client, you need:

Download the client zip file for Linux or Windows and extract its files into the same directory as the nuance directory that contains your proto files and Python stubs.

Python app file

Each sample client app package contains a common Python client application file, nlu_client.py. This file imports the generated Python stubs and contains the main application code. The client apps also include command line scripts to run the app easily on the respective platforms.

  View nlu_client.py  

Linux client run scripts

The Linux client zip file nlu-runtime-python-client-linux.zip contains, in addition to the Python app file, two run scripts for the app:

  • run-nlu-client.sh: A bash shell script that passes the OAuth URL, client ID, and secret to the Python application as arguments so that it can manage the token generation itself.
  • run-nlu-token-client.sh: A bash shell script file that generates an access token from the client id and secret and then runs the application.
#!/bin/bash

echo "Setting CLIENT_ID and SECRET"

export CLIENT_ID="ENTER YOUR MIX CLIENT ID HERE"
export SECRET="ENTER YOUR MIX CLIENT SECRET HERE"

echo "CLIENT_ID: " $CLIENT_ID
echo ""
echo "URL encoding CLIENT_ID"
# URL encode the client id by converting ':' characters to '%3A'
CLIENT_ID=${CLIENT_ID//:/%3A}
echo ""
echo "Updated CLIENT_ID: "$CLIENT_ID
echo ""
#'?' matches any character and '//' tells bash to replace all matches to the asterisk
echo "SECRET: "${SECRET//?/*}
echo ""

python3 nlu_client.py --oauthURL "https://auth.crt.nuance.com/oauth2/token" \
    --clientID $CLIENT_ID --clientSecret $SECRET \
    --serverUrl "nlu.api.nuance.com" \
    --modelUrn "$1" \
    --textInput "$2" \
    --wordsetUrn "$3"
#!/bin/bash

echo "Setting CLIENT_ID and SECRET"

export CLIENT_ID="ENTER YOUR MIX CLIENT ID HERE"
export SECRET="ENTER YOUR MIX CLIENT SECRET HERE"

echo "CLIENT_ID: " $CLIENT_ID
echo ""
echo "URL encoding CLIENT_ID"
# URL encode the client id by converting ':' characters to '%3A'
CLIENT_ID=${CLIENT_ID//:/%3A}
echo ""
echo "Updated CLIENT_ID: "$CLIENT_ID
echo ""
#'?' matches any character and '//' tells bash to replace all matches to the asterisk
echo "SECRET: "${SECRET//?/*}
echo ""

export TOKEN="`curl -s -u "$CLIENT_ID:$SECRET" "https://auth.crt.nuance.com/oauth2/token" \
-d "grant_type=client_credentials" -d "scope=nlu" \
| python -c 'import sys, json; print(json.load(sys.stdin)["access_token"])'`"

python3 nlu_client.py --serverUrl nlu.api.nuance.com \
    --token $TOKEN \
    --modelUrn "$1" \
    --textInput "$2" \
    --wordsetUrn "$3"

Give the two shell scripts execute permission with chmod +x.

chmod +x *.sh

Windows client

The Windows client zip file nlu-runtime-python-client-win.zip contains in addition to the Python app file and audio file, two run scripts for the app:

  • run-nlu-client.bat: A bash shell script that passes the OAuth URL, client ID, and secret to the Python application as arguments so that it can manage the token generation itself.
  • run-nlu-token-client.bat: A Windows batch script file that generates an access token from the client id and secret and then runs the application.
@echo off
setlocal enabledelayedexpansion

echo Setting CLIENT_ID and SECRET

set CLIENT_ID=ENTER YOUR MIX CLIENT ID HERE
set SECRET=ENTER YOUR MIX CLIENT SECRET HERE

echo CLIENT_ID:  %CLIENT_ID%
echo.
echo URL encoding CLIENT_ID

rem URL encoding CLIENT_ID by converting colons (:) to %3A 
set CLIENT_ID=!CLIENT_ID::=%%3A!
echo.
echo Updated CLIENT_ID: %CLIENT_ID%
echo.

rem Masking secret before displaying on command line
set buildMask=
set num=0
set repl=*

:strMask_Loop
call set tmp=%%SECRET:~%num%,1%%%
set /a num+=1
if not "%tmp%" equ "" (
set buildMask=%repl%%buildMask%
goto strMask_Loop
)

echo SECRET: %buildMask%

python nlu_client.py --oauthURL https://auth.crt.nuance.com/oauth2/token ^
    --clientID %CLIENT_ID% --clientSecret %SECRET% ^
    --serverUrl nlu.api.nuance.com ^
    --modelUrn %1 ^
    --textInput %2 ^
    --wordsetUrn %3
@echo off
setlocal enabledelayedexpansion

echo Setting CLIENT_ID and SECRET

set CLIENT_ID=ENTER YOUR MIX CLIENT ID HERE
set SECRET=ENTER YOUR MIX CLIENT SECRET HERE

echo CLIENT_ID:  %CLIENT_ID%
echo.
echo URL encoding CLIENT_ID

rem URL encoding CLIENT_ID by converting colons (:) to %3A 
set CLIENT_ID=!CLIENT_ID::=%%3A!
echo.
echo Updated CLIENT_ID: %CLIENT_ID%
echo.

rem Masking secret before displaying on command line
set buildMask=
set num=0
set repl=*

:strMask_Loop
call set tmp=%%SECRET:~%num%,1%%%
set /a num+=1
if not "%tmp%" equ "" (
set buildMask=%repl%%buildMask%
goto strMask_Loop
)

echo SECRET: %buildMask%

set command=curl -s -u "%CLIENT_ID%:%SECRET%"  ^
-d "grant_type=client_credentials" -d "scope=nlu" ^
"https://auth.crt.nuance.com/oauth2/token"

for /f "delims={}" %%a in ('%command%') do (
  for /f "tokens=1 delims=:, " %%b in ("%%a") do set key=%%b
  for /f "tokens=2 delims=:, " %%b in ("%%a") do set value=%%b
  goto done:
)

:done
rem Check if the token was found
if not !key!=="access_token" (
   echo Access token not found^^!
   pause
   exit
)

rem Remove quotes
set MY_TOKEN=!value:"=!

python nlu_client.py --serverUrl nlu.api.nuance.com ^
    --token %MY_TOKEN% ^
    --modelUrn %1 ^
    --textInput %2 ^
    --wordsetUrn %3

Client files

These are the resulting client files, above the nuance directory holding your Python stubs:

├── nlu_client.py
├── run-nlu-client.sh or run-nlu-client.bat
├── run-nlu-token-client.sh or run-nlu-token-client.bat
└── nuance
    ├── nlu
    │   ├── v1
    │   │   ├── runtime_pb2.py
    │   │   ├── runtime_pb2_grpc.py
    │   │   ├── runtime.proto
    │   │   ├── result_pb2.py
    │   │   ├── result.proto
    │   │   ├── interpretation-common_pb2.py
    │   │   ├── interpretation-common.proto
    │   │   ├── single-intent-interpretation_pb2.py
    │   │   ├── single-intent-interpretation.proto
    │   │   ├── multi-intent-interpretation_pb2.py
    │   │   └── multi-intent-interpretation.proto
    │   ├── wordset 
    │   │   └── v1beta1
    │   │       ├── wordset_pb2.py
    │   │       ├── wordset_grpc_pb2.py
    │   │       └── wordset.proto
    │   └── common
    │       └── v1beta1
    │           ├── job_pb2.py
    │           ├── job.proto
    │           ├── resource_pb2.py
    │           └── resource.proto
    └── rpc
        ├── error_details_pb2.py
        ├── error_details.proto
        ├── status_code_pb2.py
        ├── status_code.proto
        ├── status_pb2.py
        └── status.proto

Run Python client for help

For a quick check that the client is working, and to see the arguments it accepts, run it on Linux or Windows using the help (-h or --help) option.

See the results below and notice:

  • -s, --serverUrl: URL for the NLU server. By default this is localhost:8080 but the sample scripts specify hosted Mix NLU at nlu.api.nuance.com.

  • Authorization: Include --oauthURL, --clientID, and --clientSecret. Alternatively, generate a token and use the (hidden) --token argument. The --oauthScope is set by default to nlu and so does not need to be specified for the provided Python client, which does not require any other scopes.

  • --modelUrn: Mix URN for the NLU model.

  • --wordsetUrn: (Optional) Mix URN for the compiled wordset.

  • --textInput: Text input to interpret.

$ python nlu_client.py -h
usage: nlu_client.py [-options]

options:
  -h, --help                               Show this help message and exit
  --oauthURL [oauthUrl]                    OAuth 2.0 URL
  --clientID [clientID]                    OAuth 2.0 Client ID
  --clientSecret [clientSecret]            OAuth 2.0 Client Secret
  --oauthScope [oauthScope]                OAuth 2.0 Scope, default=nlu 
  -s [serverUrl], --serverUrl [serverUrl]  NLU server URL, default=localhost:8080
  --modelUrn [modelUrn]                    NLU Model URN
  --wordsetUrn [wordsetUrn]                compiled wordset URN
  --textInput [file]                       Text to perform interpretation on

Overview of the application

The Python client requests and receives an NLU interpretation, and also performs these tasks:

  • Imports the the contents of the generated client stub files in nuance/nlu/v1/.
  • Collects parameters from the command line:
    • NLUaaS Server URL
    • NLU model URN
    • Text to interpret
    • (Optionally) compiled wordset URN
    • OAuth information or alternatively, OAuth token
  • Sets interpretation parameters such as result type and logging mode.
  • Obtains an OAuth token to access the service
  • Calls NLU on a secure channel (authorized by the token), sending it the parameters, resource, and input text.
  • Prints the results to JSON format.

Procedure

To run the app, perform the following steps.

Edit run script to add authorization credentials

NLUaaS is a hosted service on the Nuance Mix platform. To access this service, your client applications must be authorized with an access token generated by the OAuth 2 protocol.

In order to request a token, you need your Mix client ID and secret. With these credentials, you can request an access token in several ways.

The sample client supports two methods.

Let Python client generate token

The Python client includes token-generation code, checking first to see whether the token has expired. To use this method, pass your credentials and the location of the OAuth server in the --clientID, --clientSecret, and --oauthURL arguments. This is the preferred method.

Edit your run script to add your Mix client ID and secret.

#!/bin/bash 

echo "Setting CLIENT_ID and SECRET"

export CLIENT_ID="ENTER YOUR MIX CLIENT ID HERE"
export SECRET="ENTER YOUR MIX CLIENT SECRET HERE"
@echo off
setlocal enabledelayedexpansion

echo Setting CLIENT_ID and SECRET

set CLIENT_ID=ENTER YOUR MIX CLIENT ID HERE
set SECRET=ENTER YOUR MIX CLIENT SECRET HERE

Generate token manually

Alternatively, you may generate the token manually and pass it to the client as an environment variable in the --token argument.

This token expires after a short time (around 15 minutes) so must be regenerated frequently. Not however that the number of requests is limited for security reasons.

Similarly to the case of letting the client generate the token, edit the script to add your Mix client ID and secret.

#!/bin/bash 

echo "Setting CLIENT_ID and SECRET"

export CLIENT_ID="ENTER YOUR MIX CLIENT ID HERE"
export SECRET="ENTER YOUR MIX CLIENT SECRET HERE"
@echo off
setlocal enabledelayedexpansion

echo Setting CLIENT_ID and SECRET

set CLIENT_ID=ENTER YOUR MIX CLIENT ID HERE
set SECRET=ENTER YOUR MIX CLIENT SECRET HERE

The script takes the client ID and secret and uses them to make a curl call to the authorization service and obtain a token.

export TOKEN="`curl -s -u "$CLIENT_ID:$SECRET" "https://auth.crt.nuance.com/oauth2/token" \
-d "grant_type=client_credentials" -d "scope=nlu" \
| python -c 'import sys, json; print(json.load(sys.stdin)["access_token"])'`"
set command=curl -s -u "%CLIENT_ID%:%SECRET%"  ^
-d "grant_type=client_credentials" -d "scope=nlu" ^
"https://auth.crt.nuance.com/oauth2/token"

for /f "delims={}" %%a in ('%command%') do (
  for /f "tokens=1 delims=:, " %%b in ("%%a") do set key=%%b
  for /f "tokens=2 delims=:, " %%b in ("%%a") do set value=%%b
  goto done:
)

:done
rem Check if the token was found
if not !key!=="access_token" (
   echo Access token not found^^!
   pause
   exit
)

rem Remove quotes
set MY_TOKEN=!value:"=!

Note that the scope in the authorization request in the run script includes nlu as required to get a token giving access the NLUaaS API.

Run the client

Run the client from the shell script, passing it parameters.

With the run scripts edited to include valid authorization credentials, run the client from the Linux shell or Windows command line via the run-mix-client.sh shell script or run-mix-client.bat batch script. Pass in the modelUrn, textInput, and optionally, wordsetUrn parameters as command line arguments:

./run-nlu-client.sh modelUrn textInput wordsetUrn
run-nlu-client.bat modelUrn textInput wordsetUrn

So, for example:

./run-nlu-client.sh "urn:nuance-mix:tag:model/bakery/mix.nlu?=language=eng-USA" "I'd like to order a strawberry latte" "urn:nuance-mix:tag:wordset:wordset:lang/bakery/item_names/eng-USA/mix.nlu"
run-nlu-client.bat "urn:nuance-mix:tag:model/bakery/mix.nlu?=language=eng-USA" "I'd like to order a strawberry latte" "urn:nuance-mix:tag:wordset:lang/bakery/item_names/eng-USA/mix.nlu"

The NLU engine returns the results:

{
  "status": {
    "code": 200,
    "message": "OK"
  },
  "result": {
    "literal": "I'd like to order a strawberry latte",
    "interpretations": [
      {
        "single_intent_interpretation": {
          "intent": "PLACE_ORDER",
          "confidence": 0.9961925148963928,
          "origin": "STATISTICAL",
          "entities": {
            "PRODUCT": {
              "entities": [
                {
                  "text_range": {
                    "start_index": 31,
                    "end_index": 36
                  },
                  "confidence": 0.9177429676055908,
                  "origin": "STATISTICAL",
                  "string_value": "latte"
                }
              ]
            },
            "FLAVOR": {
              "entities": [
                {
                  "text_range": {
                    "start_index": 20,
                    "end_index": 30
                  },
                  "confidence": 0.9367110133171082,
                  "origin": "STATISTICAL",
                  "string_value": "strawberry"
                }
              ]
            }
          }
        }
      }
    ]
  }
}

Here we show the details for the “client generates token” option using run-nlu-client.sh or run-nlu-client.bat. Details for the Linux and Windows token-generating run scripts are similar for the manual token generation option using run-nlu-token-client.sh or run-nlu-token-client.bat respectively. The scripts are structured such that the calls are identical—simply replace the name of the script file for the alternate script from the same platform client app.