はじめに
- AWS S3にアップロードされたデータが、ファイル命名規則に沿っているかチェックします。
- チェック結果はSlackに通知
- 規則に沿っている場合、後工程に繋げることもできます(ex.機械学習モデルのの推論呼び出し)。
- 今回はその前段階です。
- AWS上での機械学習モデルの学習や、推論は以下の記事を参照ください。
前提
- AWSのアカウントは作成済み
- SlackのWorkspaceに所属している
手順
- Step.1 Slackの設定
- Step.2 データをアップロードするS3の作成
- Step.3 Lambda関数の作成
- Step.4 Lambda関数の修正
Step.1 : Slackの設定
Incoming Webhookは、アプリケーションからSlackへの通知が行える機能です。
この設定を終えると、URLが提供され、アプリケーション(今回はlambda)がそのURLにPOSTを送ることで通知が飛ぶようになります。
1.1. Incoming Webhookを登録
SlackAppから登録します。
Incoming Webhook
を検索し、Slackに追加
ボタンを押下します。
1.2. チャンネル選択
チャンネルを選択
から、通知を送るチャンネルを選択します。
本記事では#lambda-post
というチャンネルを選択しました。
最後にIncoming Webhookインテグレーションの追加
を押下します。
1.3. Webhook URLを記録
設定後の画面にWebhook URL
の項目があるので、コピーして記録しておきましょう。
1.4. カスタマイズ
さらに、この画面では、投稿する際のslack上の名前やアイコンがカスタマイズできます。
本記事では、filename_checker
という名前を付けました。
最後に設定を保存します。
Step.2 データをアップロードするS3の作成
S3はクラウド型のオブジェクトストレージサービスです。
バージョニング機能、ログ記録、アクセス権限などを持ちます。
この設定を終えると、オブジェクトを置くバケットが作成されます。
2.1. S3へのアクセス
AWSコンソールにログインをし、S3にアクセスします。
2.2. バケットの作成
- S3にて
バケットを作成する
を押下します。
- 作成画面でバケット名とリージョンを指定します。
本記事ではorigin-data
とアジアパシフィック(東京)
を指定しています。
- 左下の
作成
ボタンを押下します。
Step.3 lambdaの作成
Lambdaはサーバーレスコンピューティングのサービスで、「何かのイベントをトリガーにして決められた処理を行う」という特徴があります。
この設定を終えると、Step.2で作成したS3にオブジェクトが作成された場合に、ログ出力(デフォルト)がされるようになります。
具体的な処理内容を追加するのはStep.4で行います。
3.1. Lambdaへのアクセス
AWSコンソールにログインをし、Lambdaにアクセスします。
3.2. 関数の作成
- 左メニューの一覧から
関数
を選択し、右上の関数の作成
を押下します。
-
一から作成
を選択し、関数名を入力、ランタイムを選択します。
本記事では、関数名はs3-trigger-slack
、ランタイムはPython3.7
を選択しています。
- さらに
実行ロールの選択または作成
を展開し、実行ロールが基本的な Lambda アクセス権限で新しいロールを作成
であることを確認し、関数の作成
を押下します。
3.3. トリガーの追加
続いて、S3にオブジェクトが追加された際に、作成した関数が起動するように設定を行います。
- 作成後の画面から、
トリガーを追加
を選択します。
- トリガーの設定で
S3
を選択します。
- バケットはStep.2で作成したものを選択し、イベントタイプは
すべてのオブジェクト作成イベント
を選択します。サフィックスは、対象とする拡張子を入力すると良いです。本記事では.jpg
を入力しています。
- 最後に
追加
ボタンを押下します。
Step.4 Lambdaの修正
- 追加する機能は以下の2点です
- ファイル命名規則のチェック
- チェック結果のメッセージング
4.1. ファイル命名規則のチェック
- 本記事では、「英字_数字.jpg」というファイル命名規則を満たす必要があるとしています。
それ以外の規則を適用させる場合には、下記リンクを参考に、適宜、正規表現を書き換えましょう。 - 参考:初心者歓迎!手と目で覚える正規表現入門・その1「さまざまな形式の電話番号を検索しよう」
関数コードへのアクセス
関数の Designer
から $\lambda$マークのアイコンがある箱をクリックすると、ページ下部に 関数コード
が現れます。
コードの変更
コードを以下のように変更し、ページ右上の 保存
ボタンを押下します。
import json
import re
# ファイル命名規則
FILENAME_PATTERN = "[A-Za-z]+_[0-9]+.jpg"
FILANAME_PATTERN_EXPLAIN = "英字_数字.jpg (英字と数字の文字数は自由)"
def lambda_handler(event, context):
# アップロードファイルの情報を抽出
bucket = event['Records'][0]['s3']['bucket']['name']
filename = event['Records'][0]['s3']['object']['key']
# ログ出力
print("buckect : " + bucket + ", filaname = " + filename )
# ファイル名チェック
filename_check = re.match(FILENAME_PATTERN, filename)
if filename_check:
## ファイル命名規則に合致した場合
print("log : filename -> OK")
else :
## ファイル命名規則に合致しなかった場合
print("log : filename -> NG")
return {
'statusCode': 200,
'body': json.dumps('Hello from Lambda!')
}
4.2. チェック結果のメッセージング
メッセージング機能は以下の関数が担います。
※参考リンク内のコードを、メッセージ(文字列)を引数に取るように変更したものです。
4.1.で作成したif-else内でこの関数を投稿したい内容(message)を引数に呼び出すことでSlackにチェック結果を通知することが出来ます。
import urllib.request
def post_slack(message):
# データ作成
send_data = {
"username": "filename-checker",
"text": message,
}
send_text = "payload=" + json.dumps(send_data)
# URL : Step.1で記録したWebhookのURL
request = urllib.request.Request(
"https://hooks.slack.com/services/~~~~~~~~~~~~~~~~~~",
data=send_text.encode("utf-8"),
method="POST"
)
with urllib.request.urlopen(request) as response:
response_body = response.read().decode("utf-8")```
4.3. Lambda関数(全体)
以上を踏まえると、Lambda内の関数は以下のようになります。
import json
import re
import urllib.request
# ファイル命名規則
FILENAME_PATTERN = "[A-Za-z]+_[0-9]+.jpg"
FILANAME_PATTERN_EXPLAIN = "英字_数字.jpg (英字と数字の文字数は自由)"
def lambda_handler(event, context):
# アップロードファイルの情報を抽出
bucket = event['Records'][0]['s3']['bucket']['name']
filename = event['Records'][0]['s3']['object']['key']
# ログ出力
print("buckect : " + bucket + ", filaname = " + filename )
# ファイル名チェック
filename_check = re.match(FILENAME_PATTERN, filename)
if filename_check:
## ファイル命名規則に合致した場合
print("log : filename -> OK")
# slackに投稿
message = filename + """がアップロードされました。
-> ファイル命名規則に沿っています。
"""
post_slack(message)
else :
## ファイル命名規則に合致しなかった場合
print("log : filename -> NG")
# slackに投稿
message = filename + """がアップロードされました。
-> ファイル命名規則に沿っていません。
-> ファイル命名規則は""" + FILANAME_PATTERN_EXPLAIN + """です。"""
post_slack(message)
return {
'statusCode': 200,
'body': json.dumps('Hello from Lambda!')
}
def post_slack(message):
# データ作成
send_data = {
"username": "filename-checker",
"text": message,
}
send_text = "payload=" + json.dumps(send_data)
# URL : Step.1で記録したWebhookのURL
request = urllib.request.Request(
"https://hooks.slack.com/services/~~~~~~~~~~~~~~~~~~",
data=send_text.encode("utf-8"),
method="POST"
)
with urllib.request.urlopen(request) as response:
response_body = response.read().decode("utf-8")
動作チェック
以下がS3に"OK_001.jpg"と"NG_aaa.jpg"をアップした際のSlack画面です。
えらい
おわりに
ちゃんとググったら情報が出てくるから、今の時代はえらい