概要
lineを使って、送信した画像から
性別、年齢予想、表情分析を実施するbotを作成しました。
画像を送ると、分析した結果が返ってくる(3人まで同時に写っててOK)
ソースコードはこちら
(ほぼべた書きでとりあえず作ってみたら、満足してしまい
リファクタリングする気力がなくなってしまった)
使用言語、技術
- Python3.6
- AWS API Gateway
- AWS Lambda
- AWS S3
- AWS DynamoDB
- AWS rekognition
構成
引っかかったところ
s3の署名付きurlを使って画像を送ろうとしたら送れない
line botに画像を送る際には画像のurlが必要なので、
以下のようなコードで画像をリプライしようとしたらエラーになった
s3_url = generate_presigned_url(
ClientMethod='get_object',
Params={
'Bucket': BUCKET,
'Key': KEY
},
ExpiresIn=60,
HttpMethod='GET'
)
line_bot_api.reply_message(
reply_token=event.reply_token,
messages=ImageSendMessage(
original_content_url=s3_url,
preview_image_url=s3_url
)
)
LineBotApiError: status_code=400, request_id=xxxxx-xxx-xxx-xxx-xxxxxxxxxx, error_response=
{
"details": [
{
"message": "Length must be between 0 and 1000",
"property": "messages[0].originalContentUrl"
},
{
"message": "Length must be between 0 and 1000",
"property": "messages[0].previewImageUrl"
}
],
"message": "The request body has 2 error(s)"
}
url長すぎって怒られた・・・
s3の署名付きurlを発行するとurl長すぎて送れないので
新たにパブリックなs3バケットを作成し、
送信する画像をread-onlyでs3に入れてurlを取得することにした
# アクセス権を付与してput
client.put_object(ACL='public-read', Bucket=bucketname, Body=image, Key=key)
# urlは文字列結合で作成
s3_pub_url = 'https://' + bucketname + '.s3-ap-northeast-1.amazonaws.com/' + key
line_bot_api.reply_message(
reply_token=event.reply_token,
messages=ImageSendMessage(
original_content_url=s3_pub_url,
preview_image_url=s3_pub_url
)
)
s3のパブリックアクセスは使ったことがなく、
アクセス権限の云々を見よう見まねで色々いじっていたら時間がかかってしまった
lambdaでPILモジュールが読み込めない
BoundingBoxを画像上に描画するために、
PILモジュールをインポートしようとしたらエラーになった
Unable to import module 'lambda_function': cannot import name '_imaging'
ローカルでは動くのに、lambdaだとPILモジュールがインポートできなくてエラーになる
Google先生に聞いてみると、どうもPillowのライブラリはosに依存する部分があるらしい
なので、lambdaが動く環境(= Amazon Linux) にインストールしたPillowライブラリが必要らしい
参考サイト:
https://michimani.net/post/aws-use-pillow-in-lambda/
上記の記事ではdockerを使ってライブラリを作成していますが、
なんか面倒くさそうだったので、cloud9を利用してライブラリを作成することにした
- cloud9の環境作成
- lambdaのインポート
- 対象のフォルダにPillowライブラリをインストール
python3 -m pip install Pillow -t ./
- 対象のフォルダをダウンロードして、s3に上げてデプロイ
- cloud9環境は削除
お金をなるべくかけたくない精神なので、
cloud9の環境はPillowライブラリを作成するためのみに使用した
cloud9からダウンロードするとzipで圧縮されているが、
フォルダごとの圧縮なので、そのままlambdaをデプロイすると関数が呼び出せなくてエラーになる(1敗)
現状の課題、やりたいことなど
-
リファクタリング
- コードがほぼべた書きの状態。
せめてDBにアクセスする処理くらいは切り離したい
- コードがほぼべた書きの状態。
-
AWSの権限回りの整理
-
色々考えるのが面倒くさく、lambdaのiamロールに必要のない権限がついてしまっている
必要のない権限は持たないように整理したい
-
-
DynamoDBの設計
- 今までRDBしか触ったことがなかったので、イマイチ使い方、メリットなどがわかっていない。
使い方もRDBっぽくなってしまっているので、知識を増やして改めて設計を考えてみたい
- 今までRDBしか触ったことがなかったので、イマイチ使い方、メリットなどがわかっていない。