GitHub.com のASK SDK for Python (JA)のチュートリアルの補足
初めてのスキル開発のAWS Lambda用にコードを準備するのセクションで、SkillのLambdaコードをパッケージ化してデプロイする手順があるのですが、この手順が少し説明不足なので補足。
-
ローカルでskillという作業用のフォルダを作る。
-
skillフォルダ内に移動し、hello_world.py 新規で作成する。
skill └── hello_world.py
-
Pythonのスキルのコードは、クラスベースとデコレーターベースの二つの作り方があるが、どちらでも良い。クラスベースの方が、ASK SDK for Node.jsの書き方に似てるので、個人的にはわかりやすいと思う。
-
手順通り hello_world.pyの中身を記述。こちらのコードを丸ごとコピペでもOK。
-
さて、ここで「AWS Lambda用にコードを準備する」の手順に入るが、ここでは特定のフォルダへのSDKセットアップを詳しく解説
-
ターミナルを開き、skillフォルダに移動する。
$ cd Skill
-
pipコマンドで、ask-sdk-core SDKライブラリをダウンロードする。必要な依存ライブラリも一緒にダウンロードされる。
$ pip install ask-sdk-core -t .
現時点で中身はこんな感じになる。
. ├── __pycache__ ├── ask_sdk_core ├── ask_sdk_core-1.10.2.dist-info ├── ask_sdk_model ├── ask_sdk_model-1.14.0.dist-info ├── ask_sdk_runtime ├── ask_sdk_runtime-1.10.2.dist-info ├── bin ├── certifi ├── certifi-2019.6.16.dist-info ├── chardet ├── chardet-3.0.4.dist-info ├── dateutil ├── hello_world.py ├── idna ├── idna-2.8.dist-info ├── python_dateutil-2.8.0.dist-info ├── requests ├── requests-2.22.0.dist-info ├── six-1.12.0.dist-info ├── six.py ├── urllib3 └── urllib3-1.25.3.dist-info
-
ここからAWS Lambdaのエンドポイントにデプロイするためのパッケージ(ZIPファイル)を作成する。zipファイルの中身にはskillフォルダを含めてはいけないことに注意。直下にライブラリ群が入っている必要がある。また、ライブラリ群とhello_world.pyファイルも同じ階層でなければならない。
$ zip ../skill.zip -r .
これで一つ上の階層にskill.zipファイルが作成される。
├── skill │ ├── __pycache__ │ ├── ask_sdk_core │ ├── hello_world.py │ <省略> └── skill.zip
-
作成したzipファイルをAWS LambdaにアップロードすればOK
オマケ
公式のhello_world.pyを日本語で動くようにしたソースです。
hello_world.py
from ask_sdk_core.dispatch_components import AbstractExceptionHandler
from ask_sdk_model.ui import SimpleCard
from ask_sdk_model import Response
from ask_sdk_core.handler_input import HandlerInput
from ask_sdk_core.utils import is_request_type, is_intent_name
from ask_sdk_core.dispatch_components import AbstractRequestHandler
from ask_sdk_core.skill_builder import SkillBuilder
class LaunchRequetHandler(AbstractRequestHandler):
def can_handle(self, handler_input):
# type: (HandlerInput) -> bool
return is_request_type("LaunchRequest")(handler_input)
def handle(self, handler_input):
# type: (HandlerInput) -> Response
speech_text = "ようこそ、アレクサスキルキットへ、こんにちは、と言ってみてください。"
handler_input.response_builder.speak(speech_text).ask(speech_text).set_card(
SimpleCard("ハローパイソン", speech_text)).set_should_end_session(False)
return handler_input.response_builder.response
class HelloWorldIntentHandler(AbstractRequestHandler):
def can_handle(self, handler_input):
return is_intent_name("HelloWorldIntent")(handler_input)
def handle(self, handler_input):
speech_text = "こんにちは"
handler_input.response_builder.speak(speech_text).set_card(
SimpleCard("ハローパイソン", speech_text)).set_should_end_session(True)
return handler_input.response_builder.response
class HelpIntentHandler(AbstractRequestHandler):
def can_handle(self, handler_input):
return is_intent_name("AMAZON.HelpIntent")(handler_input)
def handle(self, handler_input):
speech_text = "こんにちは、と言ってみてください。"
handler_input.response_builder.speak(speech_text).ask(speech_text).set_card(
SimpleCard("ハローパイソン", speech_text)).set_should_end_session(False)
return handler_input.response_builder.response
class CancelAndStopIntentHandler(AbstractRequestHandler):
def can_handle(self, handler_input):
return is_intent_name("AMAZON.CancelIntent")(handler_input) or is_intent_name("AMAZON.StopIntent")(handler_input)
def handle(self, handler_input):
speech_text = "さようなら"
handler_input.response_builder.speak(speech_text).set_card(
SimpleCard("ハローパイソン", speech_text)).set_should_end_session(False)
return handler_input.response_builder.response
class SessionEndedRequestHandler(AbstractRequestHandler):
def can_handle(self, handler_input):
return is_request_type("SessionEndedRequest")(handler_input)
def handle(self, handler_input):
# Nothing to do
return handler_input.response_builder.response
class AllExceptionHandler(AbstractExceptionHandler):
def can_handle(self, handler_input, exception):
return True
def handle(self, handler_input, exception):
# CloudWatch Logsに例外を書き出す
print(exception)
speech_text = "すみません。もう一度言ってください"
handler_input.response_builder.speek(speech_text).ask(speech_text)
return handler_input.response_builder.response
# Lambda Handlers
sb = SkillBuilder()
sb.add_request_handler(LaunchRequetHandler())
sb.add_request_handler(HelloWorldIntentHandler())
sb.add_request_handler(HelpIntentHandler())
sb.add_request_handler(CancelAndStopIntentHandler())
sb.add_request_handler(SessionEndedRequestHandler())
sb.add_exception_handler(AllExceptionHandler())
handler = sb.lambda_handler()
モデル ja-JP.json
{
"interactionModel": {
"languageModel": {
"invocationName": "ハローパイソン",
"intents": [
{
"name": "AMAZON.CancelIntent",
"samples": []
},
{
"name": "AMAZON.HelpIntent",
"samples": []
},
{
"name": "AMAZON.StopIntent",
"samples": []
},
{
"name": "HelloWorldIntent",
"slots": [],
"samples": [
"ハロー",
"こんにちは",
"ハローと言って",
"こんにちはと言って"
]
},
{
"name": "AMAZON.NavigateHomeIntent",
"samples": []
}
],
"types": []
}
}
}