Alexa skill ki(ASK)を使って、Datadogからの回答が取れるか?
AWS re:Invent 2016出参加者にAWS Echo Dotが配られたのには、時代の変化の基調を感じざるを得ませんでした。会場で起きている光景を見て、Androidを配っていた時のGoogle appの状況をもいだしました。当時iphoneに大きく遅れていたandroid端末が、世界の主流になっている今日、Amazonが狙っていることを想像するに絶やし事ではないでしょうか。
はじめに
今後、このASKネタを使ってDatadogが新しく出したAPMの機能や、スクリプトの最終実行先のLambda関数からカスタムメトリクスをDatadogへ送信する方法などの数本のホスト(英語ポストにも挑戦した)にしていこうと思っています。そのシリーズ開始宣言として、今ポストでは、先ずcpuの値を拾ってくるところまでを書きたいと思います。
尚、ASKの基本的な知識は、国内の第一人者(僕が勝手に思っているだけかもしれませんが...)のJun Ichikawaのhatenaとqiitaの記事に任せたいと思います。
ASKでプログラムするために僕が選んだ環境(2016/12/24現在)
開発環境:
- MacOS 10.12.2
- Python 2.7.10 (pyenv&virtualenvの環境下で動作しています)
- Flask-ask (askの開発をするためのpython framework)
- Datadogpy (datadog apiのpython lib)
- ngrok (Mac上で起動したflask アプリにトンネリングするためのソフト)
テスト環境:
- Amazon develpperサイトのAlexaの開発コンソールのtest
ページ
- Echosim (自作ハードなしで、国内で唯一公式使えるテスト環境)
海外で実験した実機と比較して、音声応答までの時間が長いのと操作が煩雑なのが難点ですが、十分使えるレベルにはあると思います。
なんで、こんな環境にしたの?
個人的に、Pythonが一番安心して触れるのでこの組み合わせにしました。更にdatadogpyは、Datadogが開発しており、更新が頻繁にされ、最も安定していることも選択の理由になりました。更に、これからシリーズのポストを書く上でも、DatdogのAPMが対応しているプログラミング言語とフレームワークという点でも、pythonとflaskの組み合わせは、ベストマッチングでした。
尚、pythonを使ったASKのframeworkには、PyAlexaというモノもあります。2016年のAWS summit Tokyoの頃に、僕が書いていたASKのプロジェクトにはPyAlexaを使っていました。当時は、それしか見つけられなかったのが選択の理由でした。Flask-askが公開された現在、どちらを選ぶべきかと聞かれると、以下のようにコメントすると思います。
- AWS Lambdaを使って、手っ取り早く開発したいならPyAlexaかな〜。
- Zappaなどのserverlessの知識を試してみたい、DataogのAPMも試してみたい、会話の回答を作る部分が複雑に成り手元で開発環境を実施してみたいならFlask-askかな〜。
僕のような週末プログラマーでなければ、どちらを使っても結果は大きく違わないし、スクラッチで書いても良いと思います。最後には、スクラッチで書けるほどの知識がframeworkを使っていても必要になるのは間違いないです。
作業開始
環境構築
pythonでの開発になるので、必要なモノはpipでインストールすることができます。
$ pip install flask-ask
$ pip install datadog
次に、ngrokのdownloadページからアプリをdownloadします。
その後インストラクション有るように展開し、ngrokが起動できるように準備しておきます。展開後、僕は、~/Appricatons
に移動しておきました。
$ cd /path/to/ngrok
$ unzip ngrok.zip
$ mv ngork ~/Applications/
次に、PC上の適当の場所に、開発用のディレクトリを作ります。
$ cd ~
$ mkdir ymabiko
$ cd mymabiko
僕は、次のようなファイルとディレクトリを準備しました。
├── dogfood.py
├── speech_assets
│ ├── IntentSchema.json
│ ├── SampleUtterances.txt
│ └── customSlotTypes
│ └── LIST_OF_METRIC
├── templates.yaml
└── yamabiko.py
作成したファイルやディレクトリの名称は、自由に決めてください。尚、利用目的は以下の様になります。
name | type | 概要 |
---|---|---|
yamabiko.py | file | ASKのメインプログラムを記述していきます。 |
templates.yaml | file | 音声応答に必要な、文字列を生成するためのテンプレテーとを記述しています。 |
dogfood.py | file | Datadogへの問い合わせをするをするためのhelper関数を記述していこうと思います。 |
speech_assets | dir | Amazon DevelperサイトのASK SKillページに設定する項目を管理するディレクトリにします。 |
IntentSchema.json | file | IntentSchemaを記述しておきます。 |
SampleUtterances.txt | file | Utteranceを記述しておきます。 |
customSlotTypes | dir | IntentSchemaで使っているカスタムなSlotのサンプルを記述します。 既にAmazonによって多くのbuilt-in slot typeが準備されています。 |
LIST_OF_METRIC | file | custom slot typeのサンプルを記述します。 |
dogfood.py:
api_key
とapp_key
は、自分の環境に交わせて変更してください。
#! /usr/bin/env python
from datadog import initialize, api
import time
options = {
'api_key': '81df64ebed3a1ddf6ebf3b148e70b29e',
'app_key': 'a18c26f402f1fd0901eb291e21db769c6648cb5a'
}
initialize(**options)
def cpu_idle_query(now):
query = 'system.cpu.idle{*} by {*}'
try:
api_call_response = api.Metric.query(start=now - 60, end=now, query=query)
metric_value = api_call_response['series'][-1]['pointlist'][-1][-1]
except:
metric_value = "not able to get the value"
return metric_value
def get_metric_value(now, metric):
if metric.lower() == 'cpu':
response = cpu_idle_query(now)
elif metric.lower() == 'hdd':
response = 'not available'
else:
response = None
return response
def main():
now = int(time.time())
metrics = ['CPU', 'HDD', 'Memory']
for metric in metrics:
print get_metric_value(now, metric)
if __name__ == '__main__':
main()
yamabiko.py:
import logging
from flask import Flask, json, render_template
from flask_ask import Ask, request, session, question, statement
from dogfood import get_metric_value
import time
app = Flask(__name__)
ask = Ask(app, "/")
logging.getLogger('flask_ask').setLevel(logging.DEBUG)
@ask.launch
def launch():
card_title = render_template('card_title')
question_text = render_template('welcome')
reprompt_text = render_template('welcome_reprompt')
return question(question_text).reprompt(reprompt_text).simple_card(card_title, question_text)
@ask.intent('WhatsTheValueIntent', mapping={'metric': 'Metric'})
def metric_is(metric):
card_title = render_template('card_title')
now = int(time.time())
if metric is not None:
metric_value = get_metric_value(now, metric)
if metric_value is None:
question_text = render_template('unknown_metric_reprompt')
return question(question_text).reprompt(question_text).simple_card(card_title, question_text)
if type(metric_value) is not str:
metric_value = str(metric_value)
statement_text = render_template('known_metric_bye', metric=metric, value=metric_value)
return statement(statement_text).simple_card(card_title, statement_text)
else:
question_text = render_template('unknown_metric_reprompt')
return question(question_text).reprompt(question_text).simple_card(card_title, question_text)
@ask.session_ended
def session_ended():
return "", 200
if __name__ == '__main__':
app.run(debug=True)
templates.yaml:
card_title: Yamabiko
welcome: |
Welcome to the Hachi sample. Please tell me what metric value you need by saying like, I want cpu value
welcome_reprompt: Please tell me what metric value you need by saying like , I want cpu value
known_metric_bye: Value for {{ metric }} is {{ value }}. Have a nice day.
unknown_metric_reprompt: |
I'm not sure what you need |
Please tell me what metric value you need by saying like , I want cpu value
IntentSchema.json:
{
"intents": [
{
"intent": "WhatsTheValueIntent",
"slots": [
{
"name": "Metric",
"type": "LIST_OF_METRIC"
}
]
}
]
}
SampleUtterances.txt:
WhatsTheValueIntent I want to know {Metric}
WhatsTheValueIntent I want to know {Metric} value
WhatsTheValueIntent give me {Metric}
WhatsTheValueIntent give me {Metric} value
WhatsTheValueIntent I would like to know {Metric}
WhatsTheValueIntent I need to know {Metric}
WhatsTheValueIntent I need to know {Metric} value
WhatsTheValueIntent how about {Metric}
LIST_OF_METRIC:
cpu
hdd
network
memory
アプリの起動
flask-askの起動:
$ cd /path/to/yamabiko
$ python yamabiko.py
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger pin code: 128-893-675
起動後にファイルに変更を加えると、flask-askがファイルを変更を検知し、再起動をしなくても最新の状態でamazonからの問い合わせにかいとうしてくれるようになり、手元の環境でゴリゴリと開発を進めることができます。
ngorkの起動:
flask-askの起動時に表示された、プロトコルとport番号を付けてngrokをきどうします。http
と5000
番。僕の環境では、~/Applications
にexcutableのパスが設定されていないので以下の実行をしましす。
$ cd ~/Applications
$ ./ngrok http 5000
コマンドを実行すると、下記の様な画面がターミナル全面に表示されます。
ngrok by @inconshreveable (Ctrl+C to quit)
Session Status online
Version 2.1.18
Region United States (us)
Web Interface http://127.0.0.1:4040
Forwarding http://4c7c8258.ngrok.io -> localhost:5000
Forwarding https://4c7c8258.ngrok.io -> localhost:5000
Connections ttl opn rt1 rt5 p50 p90
0 0 0.00 0.00 0.00 0.00
ここで重要なのが、Forwardingの部分のhttps://4c7c8258.ngrok.io
なります。この情報を、Amazon developerサイトで入力することになります。又、この値は、ngrokを起動する度に更新されますので、Amazon developerサイトでその都度変更する必要があります。
Amazon Developerサイトで、Skill登録
Amazon Developer Consoleに移動し、Skillの登録をします。AWS Lambdaを使わなかった場合の設定に関して補足が必要な部分のみを書きます。(手抜きで申し訳ありません。)
Skill Information
とInteraction Model
の設定までは、AWS Lambdaを使った場合と全く同じです。先に紹介したJun Ichikawa氏の記事に書かれている内容は、多くの優良情報を含んでいるので、こちらを一読するのが最も簡単で、分かりやすいと思います。
尚僕は、Invoation name
を、"Hachi"と設定しています。従って、Echoを起動するには、”Alexa ask hachi....”と、呼びかけることになります。
次のConfiguration
の部分で、HTTPS
とNorth America
を選択し、先に確認したngrokのURLを設定するようにします。
ngrokを使っているので、SSL Certificate
の部分では、"a sub-domain of a domain that has a wildcard certificate"と書かれてる部分を選択します。
動作確認
先に紹介した方法のどちらかで、テストをしてみます。僕は、Echosim を使うことにします。
上記にamazon developer
サイトで使っている認証情報を使ってアクセスします。その後、”Alexa ask hachi....”と、語りかけていきます。
尚、同等なことは、amazon developer
サイトのTest
ページから文字列を入力し、実行結果のjsonを再生することで聴くことができます。個人的には、実機が使える環境に移動して作業を進めるのがのが最も効率でした。コードを変更しながら話しかけることで、煩雑な画面遷移が最小限に押さえられることは、とってもありがたい状況でした。
まとめ
どちらかと言うと、今回のポストはlask-askの使い方になってしまいましたね。ここまでの事が理解できていると、Datadogに関係していなくても何でも好きに新しいSkillがプログラミングできる準備ができているのでは無いかと思います。プログラムの中身的には、エラー処理がしていいない、音声の問い合わせにメトリクスの選択と回答の構築など、イケていないところは沢山ありますが、それらは今後に発展に任せたいと思います。
年明け以降に予定では、flask-askのそれぞれの機能を解説したり、もう少し色々頑張ってyamabiko(alexa上では、hachi)が色々なことができるように改善していきたいと思います。こんなことができたら良いねと言うアイディアがあれば、コメントして提案してもらえますと助かります。
又、2016年のAdvent Calenderを読んで、Datadog使ってみよう思ったら、Datadogの本家サイトから、GET STARTED FREE
をクリック、Popup内で必要情報を入力すれば、直ちにトライアルが始められます。
Author And Source
この問題について(Alexa skill ki(ASK)を使って、Datadogからの回答が取れるか?), 我々は、より多くの情報をここで見つけました https://qiita.com/jhotta/items/9c151e09a9e6c6771e5e著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .