Sample ForgetMe client

The ForgetMe API requests the deletion of customer data stored outside the Nuance event log repository. Successful requests are entered in the event logs and Nuance administrators delete the data. See ForgetMe essentials in the Mix Event logs documentation.

ASRaaS offers a simple Python client that you may download and run on Linux or Windows to request the removal of speaker profiles. To run this client, you need:

Download the zip file and extract its files into the same directory as the nuance directory containing your proto files and client stubs. If you already have the util.py file from the Sample training client, you may skip it.

On Linux, give run-forgetme-client.sh execute permission with chmod +x. For example:

unzip sample-forgetme-client.zip
chmod +x run-forgetme-client.sh
pip install requests
pip install requests
  Python client, forgetme-client.py  

These are the resulting client files, in the same directory as the nuance directory:

├── forgetme-client.py
├── forgetme-flow.py
├── run-forgetme-client.bat
├── run-forgetme-client.sh
├── init.py
└── nuance
    ├── asr
    │   ├── forgetme  
    │   │   └── v1   
    │   │       ├── forgetme_pb2_grpc.py  
    │   │       └── forgetme_pb2.py  
    │   ├── v1      [ASR Recognizer files, if present]
    │   └── v1beta1 [ASR Training files, if present]
    └── rpc
        ├── error_details_pb2.py
        ├── status_code_pb2.py
        └── status_pb2.py 

This scenario deletes a speaker profile that was defined in the Recognizer API as follows:

# Define speaker profile   
speaker_profile = RecognitionResource(   
    external_reference = ResourceReference(   
        type = 'SPEAKER_PROFILE')
)   
# Include profile in RecognitionInitMessage   
init = RecognitionInitMessage(   
    parameters = RecognitionParameters( ... ),    
    resources = [ speaker_profile ],   
    user_id = 'james.somebody@aardvark.com'
)

Get help

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

See the results below and notice:

  • -f or --files: The input file or files containing your ForgetMe input and parameters. The default is forgetme-flow.py. For multiple files, specify --files flow1.py flow2.py

  • -s or --serverUrl: The URL of the ForgetMe service. The sample script specifies the Mix service, asr.api.nuance.com, on its default port, 443.

  • Authorization arguments: The recommended arguments are --oauthURL, --clientID, and --clientSecret. See Credentials for ForgetMe.

  • --token: This hidden argument specifies an access token. If you use it, omit the other authorization arguments. See Another authorization method.

  • --oauthScope: The default is set to asr.forgetme, as required by the ForgetMe API.

  • The --rootCerts, --privateKey, --certChain, and --jaeger arguments are not used in this hosted Mix environment.

  • --userId: The user ID that identifies the speaker profile to delete. When provided, this argument overrides the value set in the input flow file.

The results are the same on Linux and Windows.

python3 forgetme-client.py --help

usage: forgetme-client.py [-options]

options:
  -h, --help                     Show this help message and exit
  -f file [file ...], --files file [file ...]
                                 List of flow files to execute sequentially,
                                 default=['forgetme-flow.py']
  -l lvl, --loglevel lvl         Log level: fatal, error, warn, default=info, debug
  -L [fn], --logfile [fn]        log to file, default fn=fmsgcli-{datetimestamp}.log
  -q, --quiet                    Disable console logging
  -p, --parallel                 Run each flow in a separate thread
  -i [num], --iterations [num]   Number of times to run the list of files, default=1
  -s [url], --serverUrl [url]    ForgetMe service URL, default=localhost:9080
  -b, --disableBasicAuth         Basic auth is required for Mix-generated credentials,
                                 disable for others
  --oauthURL [url]               OAuth 2.0 URL
  --clientID [url]               OAuth 2.0 Client ID
  --clientSecret [url]           OAuth 2.0 Client Secret
  --oauthScope [url]             OAuth 2.0 Scope, default=asr
  --secure                       Connect to the server using a secure gRPC channel
  --rootCerts [file]             Root certificates when using a secure gRPC channel
  --privateKey [file]            Certificate private key when using a secure gRPC
                                 channel
  --certChain [file]             Certificate chain when using a secure gRPC channel
  --jaeger [addr]                Send UDP opentrace spans, default
                                 addr=udp://localhost:6831
  --meta [txtfile]               Read header:value metadata lines from file,
                                 default=.metadata
  --maxReceiveSizeMB [megabytes] Maximum length of gRPC server response in megabytes,
                                 default=50 MB
  --userId [url]                 User ID of speaker profile, if provided overrides the
                                 request.user_id

Edit run script

First, edit the sample shell script or batch file to add your Mix client ID and secret. The script replaces the colons in the client ID with %3A so the value can be parsed correctly in subsequent operations.

#!/bin/bash

CLIENT_ID=<Mix client ID, starting with appID:>
SECRET=<Mix client secret>
# Change colons (:) to %3A in client ID
CLIENT_ID=${CLIENT_ID//:/%3A}

python3 forgetme-client.py --secure \
--clientID $CLIENT_ID --clientSecret $SECRET \
--serverUrl asr.api.nuance.com:443 \
--oauthURL https://auth.crt.nuance.com/oauth2/token \
--userId=$1

# $1 - Optionally, the user ID of the speaker profile to delete, to override the one in forgetme-flow.py
@echo off
setlocal enabledelayedexpansion

set CLIENT_ID=< Mix client ID, starting with appID:>
set SECRET=<Mix client secret>
rem Change colons (:) to %3A in client ID
set CLIENT_ID=!CLIENT_ID::=%%3A!

python forgetme-client.py --secure ^
--clientID %CLIENT_ID% --clientSecret %SECRET% ^
--serverUrl asr.api.nuance.com:443 ^
--oauthURL https://auth.crt.nuance.com/oauth2/token ^
--userId=%1

rem %1 - Optionally, the user ID of the speaker profile to delete, to override the one in forgetme-flow.py

Edit input file (optional)

Optionally edit the input file, forgetme-flow.py, to set the speaker profile to delete. Alternatively, you can specify the speaker profile when you run the client. Optionally change the client_data value to your operating system.

from nuance.asr.forgetme.v1.forgetme_pb2 import *

list_of_requests = []

request = DeleteSpeakerProfilesRequest()

request.user_id = "socha.someone@aardvark.com"
request.client_data['app_os'] = 'IOS'

#Add request to list
list_of_requests.append(request)

Run ForgetMe client

Run the client using the shell script or batch file, optionally passing it your speaker profile ID to override the value in forgetme-flow.py. The script calls the ForgetMe service to request the removal of the speaker profile.

The service returns OK if it finds and successfully deletes the profile, or NOT_FOUND if it does not find it. The results are the same on Linux and Windows.

./run-forgetme-client.sh james.somebody@aardvark.com

2022-04-27 12:13:52,147 INFO : Iteration #1
2022-04-27 12:13:52,148 INFO : Running flows in serial
2022-04-27 12:13:52,148 INFO : Obtaining auth token using basicAuth(...)
2022-04-27 12:13:52,703 INFO : Running file [forgetme-flow.py]
2022-04-27 12:13:52,703 INFO : Sending DeleteSpeakerProfiles request
2022-04-27 12:13:52,704 INFO : Override the request user_id with argument userId [james.somebody@aardvark.com]
2022-04-27 12:13:52,704 INFO : Sending request: user_id: "james.somebody@aardvark.com"
client_data {
  key: "app_os"
  value: "CENTOS"
}

2022-04-27 12:13:52,704 INFO : Sending metadata: []
2022-04-27 12:13:53,021 INFO : Received response: status {
  status_code: OK
  http_trans_code: 200
  status_message {
    locale: "en-US"
    message: "OK"
    message_resource_id: "1"
  }
}

2022-04-27 12:13:53,022 INFO : First chunk latency: 0.31836267467588186 seconds
2022-04-27 12:13:53,022 INFO : Done running file [forgetme-flow.py]
2022-04-27 12:13:53,023 INFO : Iteration #1 complete
2022-04-27 12:13:53,023 INFO : Average first-chunk latency (over 1 requests): 0.31836267467588186 seconds
Done
run-forgetme-client.bat james.somebody@aardvark.com

2023-06-20 13:33:33,040 INFO : Iteration #1
2023-06-20 13:33:33,040 INFO : Running flows in serial
2023-06-20 13:33:33,040 INFO : Obtaining auth token using basicAuth(...)
2023-06-20 13:33:33,406 INFO : Running file [forgetme-flow.py]
2023-06-20 13:33:33,406 INFO : Sending DeleteSpeakerProfiles request
2023-06-20 13:33:33,406 INFO : Override the request user_id with argument userId [james.somebody@aardvark.com]
2023-06-20 13:33:33,406 INFO : Sending request: user_id: "james.somebody@aardvark.com"
client_data {
  key: "app_os"
  value: "Windows"
}

2023-06-20 13:33:33,406 INFO : Sending metadata: []
2023-06-20 13:33:33,566 INFO : Received response: status {
  status_code: OK
  http_trans_code: 200
  status_message {
    locale: "en-US"
    message: "OK"
    message_resource_id: "1"
  }
}

2023-06-20 13:33:33,566 INFO : First chunk latency: 0.1720000000204891 seconds
2023-06-20 13:33:33,566 INFO : Done running file [forgetme-flow.py]
2023-06-20 13:33:33,567 INFO : Iteration #1 complete
2023-06-20 13:33:33,567 INFO : Average first-chunk latency (over 1 requests): 0.1720000000204891 seconds
Done

In this example, the speaker profile identified as device-1234 was not found so could not be removed:

./run-forgetme-client.sh device-1234

...
2022-04-21 09:39:19,274 INFO : Sending request: user_id: "device-1234"

2022-04-21 09:39:19,274 INFO : Sending metadata: []
2022-04-21 09:39:19,496 INFO : Received response: status {
  status_code: NOT_FOUND
  status_sub_code: 6001
  http_trans_code: 404
  status_message {
    locale: "en-US"
    message: "Content not found for userId"
    message_resource_id: "6001"
  }
}

Another authorization method

The shell script provided with the sample client passes your Mix credentials to the client. The client generates a token that authorizes it to use the ForgetMe service. This is the recommended method as it only generates a new token when the existing one is about to expire.

For testing purposes, you may instead generate a token and pass it to the client. Copy the following code into a shell script or batch file. On Linux, give the shell script execute permission with chmod +x.

#!/bin/bash

CLIENT_ID=<Mix client ID, starting with appID: >
SECRET=<Mix client secret>
#Change colons (:) to %3A in client ID
CLIENT_ID=${CLIENT_ID//:/%3A}

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

python3 forgetme-client.py --secure --token $MY_TOKEN \
--serverUrl asr.api.nuance.com:443 \
--userId=$1

# $1 - Optionally, the user ID of the speaker profile to delete, to override the one in forgetme-flow.py
@echo off
setlocal enabledelayedexpansion

set CLIENT_ID=< Mix client ID, starting with appID:>
set SECRET=<Mix client secret>
rem Change colons (:) to %3A in client ID
set CLIENT_ID=!CLIENT_ID::=%%3A!

set command=curl -s ^
-u %CLIENT_ID%:%SECRET% ^
-d "grant_type=client_credentials" -d "scope=asr.forgetme" ^
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 Remove quotes
set MY_TOKEN=!value:"=!

python forgetme-client.py --secure --token %MY_TOKEN% ^
--serverUrl asr.api.nuance.com:443 ^
--userId=%1

rem %1 - Optionally, the user ID of the speaker profile to delete, to override the one in forgetme-flow.py

The results are the same as when you pass your credentials to the client and let the client generate the token when required.