Changing a param to body to avoid URL encoding

pull/129/head
Jim Bennett 4 years ago
parent fb025193fb
commit 661b7ee4e6

@ -66,7 +66,7 @@ When you are happy with an iteration, you can publish it to make it available to
Iterations are published from the Custom Vision portal. Iterations are published from the Custom Vision portal.
1. Launch the Custom Vision portal at [CustomVision.ai](https://customvision.ai) and sign in if you don't have it open already. 1. Launch the Custom Vision portal at [CustomVision.ai](https://customvision.ai) and sign in if you don't have it open already. Then open your `fruit-detector` project.
1. Select the **Performance** tab from the options at the top 1. Select the **Performance** tab from the options at the top

@ -348,10 +348,11 @@ Rather than calling LUIS from the IoT device, you can use serverless code with a
This loads the values you added to the `local.settings.json` file for your LUIS app, creates a credentials object with your API key, then creates a LUIS client object to interact with your LUIS app. This loads the values you added to the `local.settings.json` file for your LUIS app, creates a credentials object with your API key, then creates a LUIS client object to interact with your LUIS app.
1. This HTTP trigger will be called passing the text to understand as an HTTP parameter. These are key/value pairs sent as part of the URL. For this app, the key will be `text` and the value will be the text to understand. The following code extracts the value from the HTTP request, and logs it to the console. Add this code to the `main` function: 1. This HTTP trigger will be called passing the text to understand as JSON, with the text in a property called `text`. The following code extracts the value from the body of the HTTP request, and logs it to the console. Add this code to the `main` function:
```python ```python
text = req.params.get('text') req_body = req.get_json()
text = req_body['text']
logging.info(f'Request - {text}') logging.info(f'Request - {text}')
``` ```
@ -448,9 +449,18 @@ Rather than calling LUIS from the IoT device, you can use serverless code with a
404 is the status code for *not found*. 404 is the status code for *not found*.
1. Run the function app and test it out by passing text to the URL. URLs cannot contain spaces, so you will need to encode spaces in a way that URLs can use. The encoding for a space is `%20`, so replace all the spaces in the text with `%20`. For example, to test "Set a 2 minutes 27 second timer", use the following URL: 1. Run the function app and test it out using curl.
[http://localhost:7071/api/text-to-timer?text=Set%20a%202%20minutes%2027%20second%20timer](http://localhost:7071/api/text-to-timer?text=Set%20a%202%20minutes%2027%20second%20timer) ```sh
curl --request POST 'http://localhost:7071/api/text-to-timer' \
--header 'Content-Type: application/json' \
--include \
--data '{"text":"<text>"}'
```
Replace `<text>` with the text of your request, for example `set a 2 minutes 27 second timer`.
You will see the following output from the functions app:
```output ```output
Functions: Functions:
@ -465,6 +475,20 @@ Rather than calling LUIS from the IoT device, you can use serverless code with a
[2021-06-26T19:45:53.746Z] Executed 'Functions.text-to-timer' (Succeeded, Id=f68bfb90-30e4-47a5-99da-126b66218e81, Duration=1750ms) [2021-06-26T19:45:53.746Z] Executed 'Functions.text-to-timer' (Succeeded, Id=f68bfb90-30e4-47a5-99da-126b66218e81, Duration=1750ms)
``` ```
The call to curl will return the following:
```output
HTTP/1.1 200 OK
Date: Tue, 29 Jun 2021 01:14:11 GMT
Content-Type: text/plain; charset=utf-8
Server: Kestrel
Transfer-Encoding: chunked
{"seconds": 147}
```
The number of seconds for the timer is in the `"seconds"` value.
> 💁 You can find this code in the [code/functions](code/functions) folder. > 💁 You can find this code in the [code/functions](code/functions) folder.
### Task - make your function available to your IoT device ### Task - make your function available to your IoT device

@ -15,7 +15,9 @@ def main(req: func.HttpRequest) -> func.HttpResponse:
credentials = CognitiveServicesCredentials(luis_key) credentials = CognitiveServicesCredentials(luis_key)
client = LUISRuntimeClient(endpoint=endpoint_url, credentials=credentials) client = LUISRuntimeClient(endpoint=endpoint_url, credentials=credentials)
text = req.params.get('text') req_body = req.get_json()
text = req_body['text']
logging.info(f'Request - {text}')
prediction_request = { 'query' : text } prediction_request = { 'query' : text }
prediction_response = client.prediction.get_slot_prediction(app_id, 'Staging', prediction_request) prediction_response = client.prediction.get_slot_prediction(app_id, 'Staging', prediction_request)

@ -6,8 +6,6 @@ import time
import wave import wave
import threading import threading
from azure.iot.device import IoTHubDeviceClient, Message, MethodResponse
from grove.factory import Factory from grove.factory import Factory
button = Factory.getButton('GPIO-HIGH', 5) button = Factory.getButton('GPIO-HIGH', 5)
@ -45,13 +43,6 @@ def capture_audio():
speech_api_key = '<key>' speech_api_key = '<key>'
location = '<location>' location = '<location>'
language = '<language>' language = '<language>'
connection_string = '<connection_string>'
device_client = IoTHubDeviceClient.create_from_connection_string(connection_string)
print('Connecting')
device_client.connect()
print('Connected')
def get_access_token(): def get_access_token():
headers = { headers = {
@ -83,6 +74,28 @@ def convert_speech_to_text(buffer):
else: else:
return '' return ''
def get_timer_time(text):
url = '<URL>'
body = {
'text': text
}
response = requests.post(url, json=body)
if response.status_code != 200:
return 0
payload = response.json()
return payload['seconds']
def process_text(text):
print(text)
seconds = get_timer_time(text)
if seconds > 0:
create_timer(seconds)
def get_voice(): def get_voice():
url = f'https://{location}.tts.speech.microsoft.com/cognitiveservices/voices/list' url = f'https://{location}.tts.speech.microsoft.com/cognitiveservices/voices/list'
@ -167,18 +180,10 @@ def handle_method_request(request):
if seconds > 0: if seconds > 0:
create_timer(payload['seconds']) create_timer(payload['seconds'])
method_response = MethodResponse.create_from_method_request(request, 200)
device_client.send_method_response(method_response)
device_client.on_method_request_received = handle_method_request
while True: while True:
while not button.is_pressed(): while not button.is_pressed():
time.sleep(.1) time.sleep(.1)
buffer = capture_audio() buffer = capture_audio()
text = convert_speech_to_text(buffer) text = convert_speech_to_text(buffer)
if len(text) > 0: process_text(text)
print(text)
message = Message(json.dumps({ 'speech': text }))
device_client.send_message(message)

@ -1,19 +1,11 @@
import json import requests
import threading import threading
import time import time
from azure.cognitiveservices.speech import SpeechConfig, SpeechRecognizer, SpeechSynthesizer from azure.cognitiveservices.speech import SpeechConfig, SpeechRecognizer, SpeechSynthesizer
from azure.iot.device import IoTHubDeviceClient, Message, MethodResponse
speech_api_key = '<key>' speech_api_key = '<key>'
location = '<location>' location = '<location>'
language = '<language>' language = '<language>'
connection_string = '<connection_string>'
device_client = IoTHubDeviceClient.create_from_connection_string(connection_string)
print('Connecting')
device_client.connect()
print('Connected')
recognizer_config = SpeechConfig(subscription=speech_api_key, recognizer_config = SpeechConfig(subscription=speech_api_key,
region=location, region=location,
@ -21,24 +13,6 @@ recognizer_config = SpeechConfig(subscription=speech_api_key,
recognizer = SpeechRecognizer(speech_config=recognizer_config) recognizer = SpeechRecognizer(speech_config=recognizer_config)
def recognized(args):
if len(args.result.text) > 0:
message = Message(json.dumps({ 'speech': args.result.text }))
device_client.send_message(message)
recognizer.recognized.connect(recognized)
recognizer.start_continuous_recognition()
speech_config = SpeechConfig(subscription=speech_api_key,
region=location)
speech_config.speech_synthesis_language = language
speech_synthesizer = SpeechSynthesizer(speech_config=speech_config)
voices = speech_synthesizer.get_voices_async().get().voices
first_voice = next(x for x in voices if x.locale.lower() == language.lower())
speech_config.speech_synthesis_voice_name = first_voice.short_name
def say(text): def say(text):
ssml = f'<speak version=\'1.0\' xml:lang=\'{language}\'>' ssml = f'<speak version=\'1.0\' xml:lang=\'{language}\'>'
ssml += f'<voice xml:lang=\'{language}\' name=\'{first_voice.short_name}\'>' ssml += f'<voice xml:lang=\'{language}\' name=\'{first_voice.short_name}\'>'
@ -70,17 +44,43 @@ def create_timer(total_seconds):
announcement += 'timer started.' announcement += 'timer started.'
say(announcement) say(announcement)
def handle_method_request(request): def get_timer_time(text):
if request.name == 'set-timer': url = '<URL>'
payload = json.loads(request.payload)
seconds = payload['seconds'] body = {
if seconds > 0: 'text': text
create_timer(payload['seconds']) }
method_response = MethodResponse.create_from_method_request(request, 200) response = requests.post(url, json=body)
device_client.send_method_response(method_response)
device_client.on_method_request_received = handle_method_request if response.status_code != 200:
return 0
payload = response.json()
return payload['seconds']
def process_text(text):
print(text)
seconds = get_timer_time(text)
if seconds > 0:
create_timer(seconds)
def recognized(args):
process_text(args.result.text)
recognizer.recognized.connect(recognized)
recognizer.start_continuous_recognition()
speech_config = SpeechConfig(subscription=speech_api_key,
region=location)
speech_config.speech_synthesis_language = language
speech_synthesizer = SpeechSynthesizer(speech_config=speech_config)
voices = speech_synthesizer.get_voices_async().get().voices
first_voice = next(x for x in voices if x.locale.lower() == language.lower())
speech_config.speech_synthesis_voice_name = first_voice.short_name
while True: while True:
time.sleep(1) time.sleep(1)

@ -76,11 +76,11 @@ def convert_speech_to_text(buffer):
def get_timer_time(text): def get_timer_time(text):
url = '<URL>' url = '<URL>'
params = { body = {
'text': text 'text': text
} }
response = requests.post(url, params=params) response = requests.post(url, json=body)
if response.status_code != 200: if response.status_code != 200:
return 0 return 0

@ -16,11 +16,11 @@ recognizer = SpeechRecognizer(speech_config=recognizer_config)
def get_timer_time(text): def get_timer_time(text):
url = '<URL>' url = '<URL>'
params = { body = {
'text': text 'text': text
} }
response = requests.post(url, params=params) response = requests.post(url, json=body)
if response.status_code != 200: if response.status_code != 200:
return 0 return 0

@ -26,14 +26,14 @@ Timers can be set using the Python `threading.Timer` class. This class takes a d
Replace `<URL>` with the URL of your rest endpoint that you built in the last lesson, either on your computer or in the cloud. Replace `<URL>` with the URL of your rest endpoint that you built in the last lesson, either on your computer or in the cloud.
1. Add the following code to set the text as a parameter on the URL and make the API call: 1. Add the following code to set the text as a property passed as JSON to the call:
```python ```python
params = { body = {
'text': text 'text': text
} }
response = requests.post(url, params=params) response = requests.post(url, json=body)
``` ```
1. Below this, retrieve the `seconds` from the response payload, returning 0 if the call failed: 1. Below this, retrieve the `seconds` from the response payload, returning 0 if the call failed:

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 467 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 624 KiB

Loading…
Cancel
Save