AWS LambdaとAPI Gatewayを触ってみたのでメモ
PyCon JP スプリントの時に id:iktakahiro さんがLambdaの話をしていたのですが、Lambda + API Gatewayは覚えとくと便利そうなので試してみた。
Lambdaを触ってみる
まずAPI Gatewayは考えずに、Lambdaを触ってみる。 調べてみたら、公式のドキュメントにも今やりたいことに似たものがあった。
https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/with-s3-example.html
事前に、下のことをしておいた。
- Lambda実行用のIAMロールを作成
- RoleType: AWS Lambda
- Policy: AWSLambdaFullAccess, AmazonS3FullAccess, AWSLambdaBasicExecutionRole
- S3のバケットを2つ用意。
- bucketとlambdaは同じリージョンに作る
hoge-image-source
: 直接アップロードされた画像hoge-image-resized
: Lambdaによってサイズを変更した画像
image-resized
にtest.jpg
という画像データを保存- Lambdaの動きを確認する時に、
test.jpg
がcreatedされたというサンプルイベントデータを渡す。
- Lambdaの動きを確認する時に、
デプロイパッケージを作成
Pillowみたいなサードパーティのライブラリを使うときは、それらを一緒にzipに固めたデプロイパッケージを作る。
デプロイパッケージに含めるものは、 id:iktakahiro さんいわく ./vendors
に入れておくのがいいらしいのでとりあえず真似してみる。
$ virtualenv -p python2.7 venv # Python3使えないので注意 $ source venv/bin/activate $ pip install pillow -t ./vendors $ ls vendors/ PIL Pillow-3.3.1.dist-info
ただ、この方法はPillowとか使う場合うまくいかなかった。
Unable to import module 'lambda_function': /var/task/PIL/_imaging.so: invalid ELF header
ではまった。どうやらMacでビルドするのが行けないらしい。 Amazon LinuxのインスタンスをEC2で立ち上げてビルドした。 Dockerでうまくビルド出来るようにすると楽になれそう。
@c_bata_ あー Pillow は駄目だねぇ。軽く使いたいだけならこういうのもあるけどね https://t.co/tMtbYU6oxB
— Takahiro Ikeuchi (@iktakahiro) October 2, 2016
こういうビルド済みのファイルを提供しているリポジトリもあるらしい。
コードを書く
thumbnail-generator.py
from __future__ import print_function import boto3 import os import sys import uuid from PIL import Image s3_client = boto3.client('s3') RESIZED_BUCKET_NAME = 'hoge-image-resized' RESIZED_IMAGE_SIZE = (200, 100) def resize_image(image_path, resized_path): with Image.open(image_path) as image: image.thumbnail(RESIZED_IMAGE_SIZE) image.save(resized_path) def lambda_handler(event, context): for record in event['Records']: bucket = record['s3']['bucket']['name'] key = record['s3']['object']['key'] download_path = '/tmp/{}{}'.format(uuid.uuid4(), key) upload_path = '/tmp/resized-{}'.format(key) s3_client.download_file(bucket, key, download_path) resize_image(download_path, upload_path) s3_client.upload_file(upload_path, RESIZED_BUCKET_NAME, key)
アップロード
10MB以上なら、S3を経由してUploadする必要がある。 10MB以下なら、Lambdaの設定画面からUpload出来る。
ログ
こんな感じでグラフ化されている。 それぞれの詳細のログも見れるので、確認したい項目はprintしておけばいいみたい。
動作確認
AWS CLIを使う方法とかもあるけど、ブラウザ上のTestボタンを押す方法が一番手軽な感じ。 CIの導入とかuploadからtestまで一発でやりたくなったら、AWS CLIを使う方法を試して追記。
Testボタン
事前に test.jpg
をアップロード済みなので、ブラウザからS3のPutイベントを発生させてみる。
管理画面でTestって名前がついた青いボタンがあるのでそれを押す。
awsRegionとbucketのarn, name, objectのkeyを変えて実行。
- awsRegion: ap-northeast-1
- s3 > object > key:
test.jpg
- s3 > bucket >
arn: arn:aws:s3:::hoge-image-source
- s3 > bucket >
name: hoge-image-source
ログを見ながらデバッグ。
うまくいくと、 hoge-image-resized
の方にサムネイルが生成されている。
Github
成果物
API Gateway
API Gatewayで画像のアップロード用APIを作りたい。 POSTで画像を受け取って、S3へアップロード、URLを返す。
リクエストの形式
まずリクエストのヘッダやボディがAPI Gateway経由でどのように渡されるのか確認する。 あとで気づいたのだけれど、API Gateway AWS ProxyのSample event templateを見ればわかった。
{ "body": "{\"test\":\"body\"}", "resource": "/{proxy+}", "requestContext": { "resourceId": "123456", "apiId": "1234567890", "resourcePath": "/{proxy+}", "httpMethod": "POST", "requestId": "c6af9ac6-7b61-11e6-9a41-93e8deadbeef", "accountId": "123456789012", "identity": { "apiKey": null, : (中略) }, "stage": "prod" }, "queryStringParameters": { "foo": "bar" }, "headers": { "Accept-Encoding": "gzip, deflate, sdch", : (中略) }, "pathParameters": { "proxy": "path/to/resource" }, "httpMethod": "POST", "stageVariables": { "baz": "qux" }, "path": "/path/to/resource" }
うん、とても分かりやすい。 楽をさせるために、request bodyはunicodeで渡されるらしい。
2016/10/04 削除
ここに色々書いてたのですが、文字列についてだいぶ大きな勘違いをしてました。 unicode形式だと画像とかファイルは受け取れないと思ってたんですが、普通にencodeすればいいだけなんですね。
レスポンスの形式
知らずにはまったんだけど、レスポンスは次の形式で返す必要がある。
よくよく考えたら、Hello World
みたいに文字列返すだけだとステータスコードとヘッダ渡す場所がないので当たり前だった。
from __future__ import print_function def lambda_handler(event, context): return { "statusCode": 200, "headers": {"headerName": "headerValue", "Foo": "bar"}, "body": "This is body" }
所感・メモ
Lambda
- Pythonは2系のみ
- 300秒まで使える
- バッチ処理とかだと厳しい場合が結構ありそう
- EC2立ち上げる人もいるらしい
- Lambda Functionはバージョニング可能
- VPC対応あり
- CloudWatch EventsのScheduleで定期実行できる
- 勝手にスケールしてくれる
API Gateway
リクエストの情報をかなりラップして渡してくれていて、手軽。
- リクエストのpayloadサイズに10MBの上限がある。画像とかファイルアップロードするときは厳しい
- 結構分かりやすい形式でLambdaにリクエストの情報を送ってくれる
- レスポンスの形式も明確
References
- AWS Lambda で本番/検証環境を切り替える - Librabuch
- Python で パッケージを vendoring しつつ AWS Lambda へデプロイ - Librabuch
- Amazon S3 プロキシとして API を作成する - Amazon API Gateway
- ステップ 2.3: Lambda 関数を作成し、手動でテストする - AWS Lambda
- Amazon API Gatewayが非常に便利なHTTPプロキシとして進化したらしいので使ってみた - Qiita
Amazon Web Services クラウドネイティブ・アプリケーション開発技法 一番大切な知識と技術が身につく (Informatics&IDEA)
- 作者: NRIネットコム株式会社,佐々木拓郎,佐藤瞬,石川修,高柳怜士,佐藤雄也,岸本勇貴
- 出版社/メーカー: SBクリエイティブ
- 発売日: 2016/04/20
- メディア: 単行本
- この商品を含むブログ (1件) を見る
#pyconjp でWeb(WSGI)フレームワークの作り方について話してきました
昨年のPyConJPでは pandas-validator について話していたのですが、今回はトークセッションをしてきました。 Twitter見てると早速スライドを見ながら実装してくださってる方もいらっしゃって嬉しいかぎりです。
日本語のWSGIフレームワークの作り方の資料としては最もまとまっているものになっていると思うので、ぜひご活用ください。
基礎から学ぶWebアプリケーションフレームワークの作り方
WSGIの解説から始まり、ルーティング・リクエスト・レスポンス・HTMLテンプレートやミドルウェアについて順番に解説しながら、ボトムアップでフレームワークを作り上げていく話をしてきました。
半分ライブコーディングみたいな形だったので、少し不安もありました。 もう少しこうやればスムーズだったかなと反省点も少しありますが、スライドとかTogetterまとめがホッテントリ入りしていたらしく、周りからの反響もよくて一安心です。
動画
2_04 基礎から学ぶWebアプリケーションフレームワークの作り方
スライド
Togetterまとめ
GitHub - c-bata/webframework-in-python: "How to develop WSGI WEB Framework" talked at PyConJP 2016
明日はマイクロソフト社さんのオフィスで、PyConJPのスプリントがありますが会場にいるので、もし質問とかあればお声がけください。
remark.js の紹介
少し話がそれるのですが、資料作りにあたって、 Remark.js が素晴らしかったので紹介。
このように
shift + c
で新しいWindowを開くshift + p
でプレゼンテーションモードに変更
するとうまく同期してくれます。 reveal.jsだと発表者ノートを表示するためにwebsocketのサーバを立ち上げないといけませんが、こちらは必要ありません。Github Pagesでも上のスライドのリンクのようにそのまま動かせます。
最高です。
全体的な感想
- 1日目のパーティで沢山の方にお声がけいただけました。有名人になれたみたいで嬉しかったです。このブログすごい参考にしてますと言ってくださる方もいらっしゃったのでしっかり更新続けないとなと思いました
- スピーカーパーティの時にPyDataの山本さんという方とお話したのですが、xgboostや競馬予測に関して本当に面白い話をお聞きすることができました。データ系に詳しい参加者がたくさんいて、普段Webをやっている人間もデータ系の全く知らなかった話を知っていけるのは、Pythonのカンファレンスならではですね。
- 非同期に関して色々と知りたいこと・よく分かってないことが多いのですが、スピーカーパーティの時にjbkingさんからめちゃくちゃ丁寧な解説をいただきました。本当に面白くてコードを書くモチベーションがめちゃくちゃ高くなってしまった。
- 来年は非同期で高速なWebフレームワークに関して発表したい
以上、おつかれさまでした。
- 作者: Michal Jaworski,Tarek Ziade,稲田直哉,芝田将,渋川よしき,清水川貴之,森本哲也
- 出版社/メーカー: KADOKAWA
- 発売日: 2018/02/26
- メディア: 単行本
- この商品を含むブログを見る
PyCon APAC 2016 in KoreaでLTしてきた
昨年の台湾の開催につづいて、今年もPyCon APAC 2016 in Koreaに参加してきました。
PyCon APACについて
PyCon APACは名前の通りアジア太平洋地域の人たちが集まるPythonのカンファレンスです。 昨年は台湾で開催されて700人ぐらいが集まりましたが、今年は韓国の開催でしたが1500人が集まったらしい。規模がかなり大きいですね
前回の参加の様子は gihyo.jp さんの方で参加レポートを連載させていただいていたのでそちらをご覧ください。
今年も gihyo.jp さんの方で参加レポートを書くので、詳細はそちらをご覧ください。
追記
公開されました
Lightning Talk
昨年につづいて今年もLTしてきました。動画はこちら↓。@terapyonさん撮影ありがとうございました :) そのうちPython KRの公式チャンネルでも公開されるかもしれません。
今動画を見てみると文法や発音の気になる箇所がありますが、これでも昨年台湾でやってきたLightning Talkに比べるとかなりマシになってそうです(実際話してる時は緊張もあるのでこうやって動画で振り返らないとわからないですね)。 昨年のLTの様子は今見るとちょっと笑えるんですがあまりにも恥ずかしい自分が写ってるのでどうしても見たいって人だけYoutubeで探してみてください。
発表が終わって席に戻る時に、このライブラリいいねって言ってくれる人がいてだいぶ救われました。
スライド
発表の内容としては以前このブログでも紹介したFeedyというフレームワークの紹介です。
2年前に進学のためにTOEICの勉強をしていた*1のですが、その後英語の勉強をかなり減らしてしまっていたので、PyConやEuroPython、DjangoConの動画で気になるものをとにかく見ながら言い回しを考えたり雰囲気を真似て練習していました。 まだまだ英語に関しては努力が足りてないですね。
発表が終わって席に戻る時に、このライブラリいいねって言ってくれる人がいてちょっと感動してました。
感想
韓国初めてだったのですが、人は優しいしビールは安いしとてもいい国でした。 Lightning Talkに関しては昨年に比べて一番成長が感じられた部分なので、やっぱり発表することは毎年続けてみます。 来年はマレーシアでPyCon APACがあるそうですよ。Lightning Talkではなく通常Talkのプロポーザル出したいですね。
あと来年からは社会人なので、USのPyConとかEuroPythonに会社のお金で行きたいな
以下、宣伝
PyCon JP
2015年から台湾・日本・韓国とPyConには3回参加してきたのですが、発表自体は全てLightning Talkしかやってませんでした。 来月開催されるPyCon JP 2016で初めてTalkセッションさせていただけることになったので、現在資料作成中です。
1日目15:30からです。是非聞きに来てください
Python入門者の集い
今月末に渋谷ヒカリエで開催される勉強会にゲストスピーカーとして呼んでいただけました。 もう一人ゲストスピーカーとして、一緒にPyCon APAC 2016 in Koreaに参加していたPyLadies Tokyoの @a_macbee さんも来るので是非来てください。
120人もいるので、今ならまだキャンセル待ちで入れると思います。
*1:その時のスコアは620でした。今はもう少し低いかもしれません