※ 公開日を勘違いしていて、翌日になってしまってスミマセン
はじめに
- この記事は Pythonその3 Advent Calendar 2019
の16日目です。 - AWS LambdaでPython3のfunctionをServerless FrameworkでDeployして公開するまでのメモです。
前提
- npmコマンドが使える状態
- serverless framework用のIAMユーザがある状態
- 公式のこの辺を参考にするとよいです(AdministratorAccessが推奨)
- dockerが使える状態
Serverless Frameworkの導入と設定
導入はnpm install一発です。
$ npm install serverless
--versionでpathが通っていることを確認します。
$ serverless --version
Framework Core: 1.59.3
Plugin: 3.2.5
SDK: 2.2.1
Components Core: 1.1.2
Components CLI: 1.4.0
事前に作っておいた、Serverless Framewrok用のIAMアカウントを、serverless config credentialsで設定します。
serverless config credentials --provider aws --key foo --secret bar
これで事前準備は終わりました。
テンプレートの生成とdeploy
Python3用のテンプレートプロジェクトを生成します。
serverless create --template aws-python3 --name aws-lambda-hello-python --path aws-lambda-hello-python
実際にファイルとしては以下のようなものが生成されます。
$ cd aws-lambda-hello-python
$ tree
.
├── handler.py
└── serverless.yml
0 directories, 2 files
上記コマンドでは、mainメソッドは生成されませんが、今回はlocalでも動作させたいと思ったので、追記しています。
import json
def hello(event, context):
body = {
"message": "Go Serverless v1.0! Your function executed successfully!",
"input": event
}
response = {
"statusCode": 200,
"body": json.dumps(body)
}
return response
# Use this code if you don't use the http event with the LAMBDA-PROXY
# integration
"""
return {
"message": "Go Serverless v1.0! Your function executed successfully!",
"event": event
}
"""
if __name__ == "__main__":
print(json.dumps(hello("","")))
コメントが多数書かれていますが、最低限必要なのは以下のみです(リージョンを指定していないので、defaultのus-east-1にデプロイされます)
service: aws-lambda-hello-python
provider:
name: aws
runtime: python3.8
functions:
hello:
handler: handler.hello
Localで少し動かしてみます。
$ pyenv local 3.8.0
$ python3 handler.py
{"statusCode": 200, "body": "{\"message\": \"Go Serverless v1.0! Your function executed successfully!\", \"input\": \"\"}"}
動きました。では、deployして動作確認してみます。
$ serverless deploy -v
(メッセージ省略)
$ serverless invoke -f hello
{
"statusCode": 200,
"body": "{\"message\": \"Go Serverless v1.0! Your function executed successfully!\", \"input\": {}}"
}
ちゃんとデプロイできたようです。
外部ライブラリの利用
- 外部ライブラリを使えるようにしたいと思います。
- numpyを導入したいのですが、nativeのライブラリは環境別にビルドが必要で、普通にLambdaで使うときは少々面倒ですが、Serverless Frameworkを使うと比較的楽になります。
venv環境を使えるようにして、numpyをinstallし、freezeします。
$ python3 -m venv .venv
$ .venv/bin/pip install numpy
$ .venv/bin/pip freeze > requirements.txt
適当にnumpyを使う処理を追記します。(meanがかえるようになります)。
import json
import numpy as np
def hello(event, context):
arr = range(1, 100+1)
mean = np.mean(arr)
body = {
"message": "Go Serverless v1.0! Your function executed successfully!",
"input": event,
"mean" : mean
}
response = {
"statusCode": 200,
"body": json.dumps(body)
}
return response
# Use this code if you don't use the http event with the LAMBDA-PROXY
# integration
"""
return {
"message": "Go Serverless v1.0! Your function executed successfully!",
"event": event
}
"""
if __name__ == "__main__":
print(json.dumps(hello("","")))
localで実行するとこんな感じです。
$ .venv/bin/python3 handler.py
{"statusCode": 200, "body": "{\"message\": \"Go Serverless v1.0! Your function executed successfully!\", \"input\": \"\", \"mean\": 50.5}"}
serverlessでrequirementsを使えるようにするプラグインをinstallします。
npm install serverless-python-requirements
serverless.ymlに追記します(plugins以下を追記)
service: aws-lambda-hello-python
provider:
name: aws
runtime: python3.8
functions:
hello:
handler: handler.hello
plugins:
- serverless-python-requirements
custom:
pythonRequirements:
dockerizePip: true
package:
include:
- handler.py
exclude:
- '**'
deployしてみます(dockerでnumpyのビルドが走り、デプロイされます)
$ serverless deploy -v
動作確認してみます。
$ serverless invoke -f hello
{
"statusCode": 200,
"body": "{\"message\": \"Go Serverless v1.0! Your function executed successfully!\", \"input\": {}, \"mean\": 50.5}"
}
ちゃんとnumpyが動いていますね!
それでは楽しいPython & Serverless生活を!