Skip to content

Commit

Permalink
async HTTP component (#3914)
Browse files Browse the repository at this point in the history
* Migrate WSGI to asyncio

* Rename wsgi -> http

* Python 3.4 compat

* Move linting to Python 3.4

* lint

* Lint

* Fix Python 3.4 mock_open + binary data

* Surpress logging aiohttp.access

* Spelling

* Sending files is a coroutine

* More callback annotations and naming fixes

* Fix ios
  • Loading branch information
balloob authored Oct 24, 2016
1 parent 9aa8881 commit 519d9f2
Show file tree
Hide file tree
Showing 45 changed files with 1,425 additions and 1,012 deletions.
6 changes: 3 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ sudo: false
matrix:
fast_finish: true
include:
- python: "3.4"
- python: "3.4.2"
env: TOXENV=py34
- python: "3.4"
- python: "3.4.2"
env: TOXENV=requirements
- python: "3.5"
- python: "3.4.2"
env: TOXENV=lint
- python: "3.5"
env: TOXENV=typing
Expand Down
1 change: 1 addition & 0 deletions homeassistant/bootstrap.py
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,7 @@ def enable_logging(hass: core.HomeAssistant, verbose: bool=False,
# suppress overly verbose logs from libraries that aren't helpful
logging.getLogger("requests").setLevel(logging.WARNING)
logging.getLogger("urllib3").setLevel(logging.WARNING)
logging.getLogger("aiohttp.access").setLevel(logging.WARNING)

try:
from colorlog import ColoredFormatter
Expand Down
32 changes: 18 additions & 14 deletions homeassistant/components/alexa.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
For more details about this component, please refer to the documentation at
https://home-assistant.io/components/alexa/
"""
import asyncio
import copy
import enum
import logging
Expand All @@ -12,6 +13,7 @@

import voluptuous as vol

from homeassistant.core import callback
from homeassistant.const import HTTP_BAD_REQUEST
from homeassistant.helpers import template, script, config_validation as cv
from homeassistant.components.http import HomeAssistantView
Expand All @@ -20,7 +22,7 @@
_LOGGER = logging.getLogger(__name__)

INTENTS_API_ENDPOINT = '/api/alexa'
FLASH_BRIEFINGS_API_ENDPOINT = '/api/alexa/flash_briefings/<briefing_id>'
FLASH_BRIEFINGS_API_ENDPOINT = '/api/alexa/flash_briefings/{briefing_id}'

CONF_ACTION = 'action'
CONF_CARD = 'card'
Expand Down Expand Up @@ -102,8 +104,8 @@ def setup(hass, config):
intents = config[DOMAIN].get(CONF_INTENTS, {})
flash_briefings = config[DOMAIN].get(CONF_FLASH_BRIEFINGS, {})

hass.wsgi.register_view(AlexaIntentsView(hass, intents))
hass.wsgi.register_view(AlexaFlashBriefingView(hass, flash_briefings))
hass.http.register_view(AlexaIntentsView(hass, intents))
hass.http.register_view(AlexaFlashBriefingView(hass, flash_briefings))

return True

Expand All @@ -128,9 +130,10 @@ def __init__(self, hass, intents):

self.intents = intents

@asyncio.coroutine
def post(self, request):
"""Handle Alexa."""
data = request.json
data = yield from request.json()

_LOGGER.debug('Received Alexa request: %s', data)

Expand Down Expand Up @@ -176,7 +179,7 @@ def post(self, request):
action = config.get(CONF_ACTION)

if action is not None:
action.run(response.variables)
yield from action.async_run(response.variables)

# pylint: disable=unsubscriptable-object
if speech is not None:
Expand Down Expand Up @@ -218,8 +221,8 @@ def add_card(self, card_type, title, content):
self.card = card
return

card["title"] = title.render(self.variables)
card["content"] = content.render(self.variables)
card["title"] = title.async_render(self.variables)
card["content"] = content.async_render(self.variables)
self.card = card

def add_speech(self, speech_type, text):
Expand All @@ -229,7 +232,7 @@ def add_speech(self, speech_type, text):
key = 'ssml' if speech_type == SpeechType.ssml else 'text'

if isinstance(text, template.Template):
text = text.render(self.variables)
text = text.async_render(self.variables)

self.speech = {
'type': speech_type.value,
Expand All @@ -244,7 +247,7 @@ def add_reprompt(self, speech_type, text):

self.reprompt = {
'type': speech_type.value,
key: text.render(self.variables)
key: text.async_render(self.variables)
}

def as_dict(self):
Expand Down Expand Up @@ -284,6 +287,7 @@ def __init__(self, hass, flash_briefings):
template.attach(hass, self.flash_briefings)

# pylint: disable=too-many-branches
@callback
def get(self, request, briefing_id):
"""Handle Alexa Flash Briefing request."""
_LOGGER.debug('Received Alexa flash briefing request for: %s',
Expand All @@ -292,21 +296,21 @@ def get(self, request, briefing_id):
if self.flash_briefings.get(briefing_id) is None:
err = 'No configured Alexa flash briefing was found for: %s'
_LOGGER.error(err, briefing_id)
return self.Response(status=404)
return b'', 404

briefing = []

for item in self.flash_briefings.get(briefing_id, []):
output = {}
if item.get(CONF_TITLE) is not None:
if isinstance(item.get(CONF_TITLE), template.Template):
output[ATTR_TITLE_TEXT] = item[CONF_TITLE].render()
output[ATTR_TITLE_TEXT] = item[CONF_TITLE].async_render()
else:
output[ATTR_TITLE_TEXT] = item.get(CONF_TITLE)

if item.get(CONF_TEXT) is not None:
if isinstance(item.get(CONF_TEXT), template.Template):
output[ATTR_MAIN_TEXT] = item[CONF_TEXT].render()
output[ATTR_MAIN_TEXT] = item[CONF_TEXT].async_render()
else:
output[ATTR_MAIN_TEXT] = item.get(CONF_TEXT)

Expand All @@ -315,15 +319,15 @@ def get(self, request, briefing_id):

if item.get(CONF_AUDIO) is not None:
if isinstance(item.get(CONF_AUDIO), template.Template):
output[ATTR_STREAM_URL] = item[CONF_AUDIO].render()
output[ATTR_STREAM_URL] = item[CONF_AUDIO].async_render()
else:
output[ATTR_STREAM_URL] = item.get(CONF_AUDIO)

if item.get(CONF_DISPLAY_URL) is not None:
if isinstance(item.get(CONF_DISPLAY_URL),
template.Template):
output[ATTR_REDIRECTION_URL] = \
item[CONF_DISPLAY_URL].render()
item[CONF_DISPLAY_URL].async_render()
else:
output[ATTR_REDIRECTION_URL] = item.get(CONF_DISPLAY_URL)

Expand Down
Loading

0 comments on commit 519d9f2

Please sign in to comment.