DashをAWS Lambda上にZappaでデプロイする
データ分析WebアプリケーションフレームワークであるDashをAWS Lambda(以下Lambda)上にデプロイする方法について説明します。 LambdaへのデプロイはZappaを使って行います。
Dashについて
DashはPlotly Technologies社によって開発されているデータ分析Webアプリケーションフレームワークです。同じく同社が開発しているデータ可視化ライブラリであるPlotly.jsを使用したWebアプリケーションを効率的に作成できます。
今回はこのDashを使ったアプリケーションをLambada上にデプロイし、サーバレスでデータ分析のダッシュボードを作る手順を説明します。
Zappaについて
Zappaは、pythonのwebアプリケーションをAmazon API Gateway(以下API Gateway)とLambda上で動かせるようにしてくれます。つまり、Flaskのような常時立ち上がっていることを想定しているWebアプリケーションをアクセスがあったときだけ起動するイベント駆動のサーバレスアプリケーションとして運用できることになります。その結果、アイドル時のコストを削減することができます。
Dashのサンプルアプリケーションの用意
仮想環境の構築
Zappaが仮想環境を前提とするため、仮想環境を作ります。
python3 -m venv xxx
source xxx/bin/activate
Dashのインストール
python3 -m pip install dash plotly pandas
Dashアプリケーション
Dashでの簡易なアプリケーションを記述します。
import plotly.express as px
import dash
from dash import html, dcc
from dash.dependencies import Input, Output
# サンプルデータを読み込む
df = px.data.gapminder()
# アプリケーションを作成する
app = dash.Dash(__name__)
# グラフを作成する
def create_graph(data, x_col, y_col):
fig = px.scatter(data, x=x_col, y=y_col, color='continent',
log_x=True, size_max=60, title=f"{y_col} vs {x_col}")
return fig
# レイアウトを定義する
app.layout = html.Div([
html.H1("gapminder data"),
html.Div([
dcc.Graph(id='graph-1'),
dcc.Graph(id='graph-2'),
dcc.Graph(id='graph-3')
]),
html.Div([
dcc.Dropdown(
id='x-column',
options=[{'label': i, 'value': i} for i in df.columns],
value='gdpPercap'
)
], style={'width': '25%', 'display': 'inline-block'}),
html.Div([
dcc.Dropdown(
id='y-column',
options=[{'label': i, 'value': i} for i in df.columns],
value='lifeExp'
)
], style={'width': '25%', 'display': 'inline-block'}),
])
# コールバックを定義する
@app.callback(
[Output('graph-1', 'figure'),
Output('graph-2', 'figure'),
Output('graph-3', 'figure')],
[Input('x-column', 'value'),
Input('y-column', 'value')])
def update_graph(x_col, y_col):
fig1 = create_graph(df, x_col, y_col)
fig2 = create_graph(df, y_col, x_col)
fig3 = create_graph(df, 'year', y_col)
return fig1, fig2, fig3
dapp = app.server.wsgi_app
if __name__ == '__main__':
app.run_server(debug=True, host="0.0.0.0")
詳細な説明は割愛しますが、3つのグラフを表示するものになります。
ポイントは2点です。
- ローカル環境で確認するときは、
app.run_server(debug=True, host="0.0.0.0")
により、サーバが立ち上がります。
- Zappaでは、API GatewayのイベントをLambdaのイベントとしてバイパスするために、アプリケーションのインスタンスを指定する必要があります。そのために、
dapp = app.server.wsgi_app
のようにして、アプリケーションのインスタンスを変数dappに入れています。
このファイルをapp.pyとして保存します。
python3 app.py
でアプリケーションが立ち上がるので、ブラウザでhttp://localhost:8050/にアクセスして表示されれば成功です。
ZappaでAWS環境上にデプロイ
前提としてIAMのアクセスキーなどは設定済みとします。
Zappaのインストール
python3 -m pip install zappa
Zappaの設定ファイルの用意
{
"dev": {
"app_function": "app.dapp",
"project_name": "任意のproject名",
"aws_region": "ap-northeast-1",
"runtime": "python3.9",
"s3_bucket": "任意のバケット名",
"environment_variables": { "DASH_REQUESTS_PATHNAME_PREFIX": "/dev/" },
"memory_size": 512,
"timeout_seconds": 30,
"keep_warm": false
}
}
これをzappa_settings.jsonとして保存します。 ポイントとしては、
app_functionに先ほどのpythonのスクリプトファイルであるapp.pyのアプリケーションインスタンスを師弟するために、
"app_function": "app.dapp"
として指定しています。
また、 API Gatewayは、ステージ名をURLに含めないといけないため、
https://xxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/dev
の形式でアクセスすることになるので、 DashでのjavascriptなどのアセットのURLを/dev/配下にするために、
"environment_variables": { "DASH_REQUESTS_PATHNAME_PREFIX": "/dev/" },
を指定しています。
Zappaのデプロイ
ここまで準備ができれば、
zappa deploy dev
でデプロイできます。 実行が完了すると、
https://xxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/dev
のようにURLが表示されるので、アクセスして以下の様な画面が表示できれば成功です。