Renaming API.AI to Dialogflow (#10006)
* Rename API.AI to Dialogflow * Rename API.AI to Dialogflow
This commit is contained in:
parent
bf26b75d27
commit
28b7a3da32
2 changed files with 53 additions and 49 deletions
|
@ -1,8 +1,8 @@
|
|||
"""
|
||||
Support for API.AI webhook.
|
||||
Support for Dialogflow webhook.
|
||||
|
||||
For more details about this component, please refer to the documentation at
|
||||
https://home-assistant.io/components/apiai/
|
||||
https://home-assistant.io/components/dialogflow/
|
||||
"""
|
||||
import asyncio
|
||||
import logging
|
||||
|
@ -15,17 +15,16 @@ from homeassistant.components.http import HomeAssistantView
|
|||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
INTENTS_API_ENDPOINT = '/api/apiai'
|
||||
|
||||
CONF_INTENTS = 'intents'
|
||||
CONF_SPEECH = 'speech'
|
||||
CONF_ACTION = 'action'
|
||||
CONF_ASYNC_ACTION = 'async_action'
|
||||
|
||||
DEFAULT_CONF_ASYNC_ACTION = False
|
||||
|
||||
DOMAIN = 'apiai'
|
||||
DEPENDENCIES = ['http']
|
||||
DOMAIN = 'dialogflow'
|
||||
|
||||
INTENTS_API_ENDPOINT = '/api/dialogflow'
|
||||
|
||||
CONFIG_SCHEMA = vol.Schema({
|
||||
DOMAIN: {}
|
||||
|
@ -34,30 +33,30 @@ CONFIG_SCHEMA = vol.Schema({
|
|||
|
||||
@asyncio.coroutine
|
||||
def async_setup(hass, config):
|
||||
"""Activate API.AI component."""
|
||||
hass.http.register_view(ApiaiIntentsView)
|
||||
"""Set up Dialogflow component."""
|
||||
hass.http.register_view(DialogflowIntentsView)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
class ApiaiIntentsView(HomeAssistantView):
|
||||
"""Handle API.AI requests."""
|
||||
class DialogflowIntentsView(HomeAssistantView):
|
||||
"""Handle Dialogflow requests."""
|
||||
|
||||
url = INTENTS_API_ENDPOINT
|
||||
name = 'api:apiai'
|
||||
name = 'api:dialogflow'
|
||||
|
||||
@asyncio.coroutine
|
||||
def post(self, request):
|
||||
"""Handle API.AI."""
|
||||
"""Handle Dialogflow."""
|
||||
hass = request.app['hass']
|
||||
data = yield from request.json()
|
||||
|
||||
_LOGGER.debug("Received api.ai request: %s", data)
|
||||
_LOGGER.debug("Received Dialogflow request: %s", data)
|
||||
|
||||
req = data.get('result')
|
||||
|
||||
if req is None:
|
||||
_LOGGER.error("Received invalid data from api.ai: %s", data)
|
||||
_LOGGER.error("Received invalid data from Dialogflow: %s", data)
|
||||
return self.json_message(
|
||||
"Expected result value not received", HTTP_BAD_REQUEST)
|
||||
|
||||
|
@ -68,13 +67,13 @@ class ApiaiIntentsView(HomeAssistantView):
|
|||
|
||||
action = req.get('action')
|
||||
parameters = req.get('parameters')
|
||||
apiai_response = ApiaiResponse(parameters)
|
||||
dialogflow_response = DialogflowResponse(parameters)
|
||||
|
||||
if action == "":
|
||||
_LOGGER.warning("Received intent with empty action")
|
||||
apiai_response.add_speech(
|
||||
"You have not defined an action in your api.ai intent.")
|
||||
return self.json(apiai_response)
|
||||
dialogflow_response.add_speech(
|
||||
"You have not defined an action in your Dialogflow intent.")
|
||||
return self.json(dialogflow_response)
|
||||
|
||||
try:
|
||||
intent_response = yield from intent.async_handle(
|
||||
|
@ -83,31 +82,31 @@ class ApiaiIntentsView(HomeAssistantView):
|
|||
in parameters.items()})
|
||||
|
||||
except intent.UnknownIntent as err:
|
||||
_LOGGER.warning('Received unknown intent %s', action)
|
||||
apiai_response.add_speech(
|
||||
_LOGGER.warning("Received unknown intent %s", action)
|
||||
dialogflow_response.add_speech(
|
||||
"This intent is not yet configured within Home Assistant.")
|
||||
return self.json(apiai_response)
|
||||
return self.json(dialogflow_response)
|
||||
|
||||
except intent.InvalidSlotInfo as err:
|
||||
_LOGGER.error('Received invalid slot data: %s', err)
|
||||
_LOGGER.error("Received invalid slot data: %s", err)
|
||||
return self.json_message('Invalid slot data received',
|
||||
HTTP_BAD_REQUEST)
|
||||
except intent.IntentError:
|
||||
_LOGGER.exception('Error handling request for %s', action)
|
||||
_LOGGER.exception("Error handling request for %s", action)
|
||||
return self.json_message('Error handling intent', HTTP_BAD_REQUEST)
|
||||
|
||||
if 'plain' in intent_response.speech:
|
||||
apiai_response.add_speech(
|
||||
dialogflow_response.add_speech(
|
||||
intent_response.speech['plain']['speech'])
|
||||
|
||||
return self.json(apiai_response)
|
||||
return self.json(dialogflow_response)
|
||||
|
||||
|
||||
class ApiaiResponse(object):
|
||||
"""Help generating the response for API.AI."""
|
||||
class DialogflowResponse(object):
|
||||
"""Help generating the response for Dialogflow."""
|
||||
|
||||
def __init__(self, parameters):
|
||||
"""Initialize the response."""
|
||||
"""Initialize the Dialogflow response."""
|
||||
self.speech = None
|
||||
self.parameters = {}
|
||||
# Parameter names replace '.' and '-' for '_'
|
||||
|
@ -125,7 +124,7 @@ class ApiaiResponse(object):
|
|||
self.speech = text
|
||||
|
||||
def as_dict(self):
|
||||
"""Return response in an API.AI valid dict."""
|
||||
"""Return response in a Dialogflow valid dictionary."""
|
||||
return {
|
||||
'speech': self.speech,
|
||||
'displayText': self.speech,
|
|
@ -1,4 +1,4 @@
|
|||
"""The tests for the APIAI component."""
|
||||
"""The tests for the Dialogflow component."""
|
||||
# pylint: disable=protected-access
|
||||
import json
|
||||
import unittest
|
||||
|
@ -7,14 +7,14 @@ import requests
|
|||
|
||||
from homeassistant.core import callback
|
||||
from homeassistant import setup, const
|
||||
from homeassistant.components import apiai, http
|
||||
from homeassistant.components import dialogflow, http
|
||||
|
||||
from tests.common import get_test_instance_port, get_test_home_assistant
|
||||
|
||||
API_PASSWORD = "test1234"
|
||||
API_PASSWORD = 'test1234'
|
||||
SERVER_PORT = get_test_instance_port()
|
||||
BASE_API_URL = "http://127.0.0.1:{}".format(SERVER_PORT)
|
||||
INTENTS_API_URL = "{}{}".format(BASE_API_URL, apiai.INTENTS_API_ENDPOINT)
|
||||
INTENTS_API_URL = "{}{}".format(BASE_API_URL, dialogflow.INTENTS_API_ENDPOINT)
|
||||
|
||||
HA_HEADERS = {
|
||||
const.HTTP_HEADER_HA_AUTH: API_PASSWORD,
|
||||
|
@ -27,9 +27,9 @@ INTENT_NAME = "tests"
|
|||
REQUEST_ID = "19ef7e78-fe15-4e94-99dd-0c0b1e8753c3"
|
||||
REQUEST_TIMESTAMP = "2017-01-21T17:54:18.952Z"
|
||||
CONTEXT_NAME = "78a5db95-b7d6-4d50-9c9b-2fc73a5e34c3_id_dialog_context"
|
||||
MAX_RESPONSE_TIME = 5 # https://docs.api.ai/docs/webhook
|
||||
MAX_RESPONSE_TIME = 5 # https://dialogflow.com/docs/fulfillment
|
||||
|
||||
# An unknown action takes 8s to return. Request timeout should be bigger to
|
||||
# An unknown action takes 8 s to return. Request timeout should be bigger to
|
||||
# allow the test to finish
|
||||
REQUEST_TIMEOUT = 15
|
||||
|
||||
|
@ -46,19 +46,23 @@ def setUpModule():
|
|||
hass = get_test_home_assistant()
|
||||
|
||||
setup.setup_component(
|
||||
hass, http.DOMAIN,
|
||||
{http.DOMAIN: {http.CONF_API_PASSWORD: API_PASSWORD,
|
||||
http.CONF_SERVER_PORT: SERVER_PORT}})
|
||||
hass, http.DOMAIN, {
|
||||
http.DOMAIN: {
|
||||
http.CONF_API_PASSWORD: API_PASSWORD,
|
||||
http.CONF_SERVER_PORT: SERVER_PORT,
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
@callback
|
||||
def mock_service(call):
|
||||
"""Mock action call."""
|
||||
calls.append(call)
|
||||
|
||||
hass.services.register("test", "apiai", mock_service)
|
||||
hass.services.register('test', 'dialogflow', mock_service)
|
||||
|
||||
assert setup.setup_component(hass, apiai.DOMAIN, {
|
||||
"apiai": {},
|
||||
assert setup.setup_component(hass, dialogflow.DOMAIN, {
|
||||
"dialogflow": {},
|
||||
})
|
||||
assert setup.setup_component(hass, "intent_script", {
|
||||
"intent_script": {
|
||||
|
@ -92,7 +96,7 @@ def setUpModule():
|
|||
"text": "Service called",
|
||||
},
|
||||
"action": {
|
||||
"service": "test.apiai",
|
||||
"service": "test.dialogflow",
|
||||
"data_template": {
|
||||
"hello": "{{ ZodiacSign }}"
|
||||
},
|
||||
|
@ -112,12 +116,13 @@ def tearDownModule():
|
|||
|
||||
|
||||
def _intent_req(data):
|
||||
return requests.post(INTENTS_API_URL, data=json.dumps(data),
|
||||
timeout=REQUEST_TIMEOUT, headers=HA_HEADERS)
|
||||
return requests.post(
|
||||
INTENTS_API_URL, data=json.dumps(data), timeout=REQUEST_TIMEOUT,
|
||||
headers=HA_HEADERS)
|
||||
|
||||
|
||||
class TestApiai(unittest.TestCase):
|
||||
"""Test APIAI."""
|
||||
class TestDialogflow(unittest.TestCase):
|
||||
"""Test Dialogflow."""
|
||||
|
||||
def tearDown(self):
|
||||
"""Stop everything that was started."""
|
||||
|
@ -167,7 +172,7 @@ class TestApiai(unittest.TestCase):
|
|||
self.assertEqual("", req.text)
|
||||
|
||||
def test_intent_slot_filling(self):
|
||||
"""Test when API.AI asks for slot-filling return none."""
|
||||
"""Test when Dialogflow asks for slot-filling return none."""
|
||||
data = {
|
||||
"id": REQUEST_ID,
|
||||
"timestamp": REQUEST_TIMESTAMP,
|
||||
|
@ -424,7 +429,7 @@ class TestApiai(unittest.TestCase):
|
|||
self.assertEqual(call_count + 1, len(calls))
|
||||
call = calls[-1]
|
||||
self.assertEqual("test", call.domain)
|
||||
self.assertEqual("apiai", call.service)
|
||||
self.assertEqual("dialogflow", call.service)
|
||||
self.assertEqual(["switch.test"], call.data.get("entity_id"))
|
||||
self.assertEqual("virgo", call.data.get("hello"))
|
||||
|
||||
|
@ -471,7 +476,7 @@ class TestApiai(unittest.TestCase):
|
|||
self.assertEqual(200, req.status_code)
|
||||
text = req.json().get("speech")
|
||||
self.assertEqual(
|
||||
"You have not defined an action in your api.ai intent.", text)
|
||||
"You have not defined an action in your Dialogflow intent.", text)
|
||||
|
||||
def test_intent_with_unknown_action(self):
|
||||
"""Test a intent with an action not defined in the conf."""
|
Loading…
Add table
Reference in a new issue