はじめに
AlexaのPythonのSDKででスキルを開発する際、以下のような状況に出くわすことがあります。
- ワンショット対応のため、最初に呼ばれるリクエストハンドラを特定できない
- 起動時に実行すべき処理がある。例えばDnyamoDBからの永続アトリビュートの取得とセッションアトリビュートへの格納など
最初に呼ばれるリクエストハンドラが決まっているのであれば、そのハンドラに起動時に必要な処理を記述すればよいです。
しかし決まっていない場合、最初に呼ばれる可能性のある全てのハンドラに、起動時必要な処理を記述すべきなのでしょうか。
解決策
AbstractRequestInterceptorを継承したクラスを用意し、そのprocess関数に処理を記述します。
すると、その処理はどのリクエストハンドラが呼び出されても、そのハンドラの最初に実行されます。
そのため、各リクエストハンドラに逐一処理を書かなくてよくなります。
コード(関連部分のみ)
例えばこのように書くと、どのリクエストハンドラから呼び出された場合でも、セッションアトリビュートの有無を確認し、なければ設定します。
なお、SDKではハンドラやインターセプターの記述について、以下の二つがあります。ここでは前者を採っています。
- クラスとして記述する方法
- 関数として記述する方法
# AbstractRequestInterceptorをインポート
from ask_sdk_core.dispatch_components import AbstractRequestInterceptor
# AbstractRequestInterceptorを継承したクラス
class AnyNameInterceptor(AbstractRequestInterceptor):
"""リクエストインターセプター。各ハンドラの実行時に呼び出される"""
def process(self, handler_input):
"""各ハンドラで共通して実行させたい処理を記述
ここでは、セッションアトリビュートの有無を確認し、なければ関数get_s_attrで取得
"""
if not handler_input.attributes_manager.session_attributes:
handler_input.attributes_manager.session_attributes = get_s_attr(handler_input)
# StandardSkillBuilderへの登録
# ここではsbはStandardSkillBuilder
sb.add_global_request_interceptor(AnyNameInterceptor())
関数get_s_attrは自作です。コードは割愛しています。
最後の、StandardSkillBuilderへのインターセプターの追加は忘れがちです。
修正履歴
- 19/05/04 15:45
- この投稿のタイトルを「Alexa Skill開発用PythonのSDKの一機能であるリクエストインターセプターの使途」から変更。
- 「コード」より前の記述の観点を、コードの使途からニーズとその解決策に変更。
- コードの解説を追記
参考URL
公式ドキュメント
Alexa Skills Kit SDK for Python-JA / リクエスト処理 / リクエストと応答のインターセプター / リクエストインターセプター
https://alexa-skills-kit-python-sdk.readthedocs.io/ja/latest/REQUEST_PROCESSING.html?highlight=AbstractRequestInterceptor#id10
あたりまえですが、理解してから読むとなるほどと思います。