0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Qiita×Findy記事投稿キャンペーン 「自分のエンジニアとしてのキャリアを振り返ろう!」

ハッカソン参加時の備忘録 ~ 第5回:【Python】AWS LambdaとAWS S3を連携させてみよう ~

Last updated at Posted at 2024-02-17

こんにちは。ITエンジニアのきゅうです。
今回作成するアプリのシステム構成図です。

image.png

今までインターフェース部分としてLINEを使用しておりましたが、動かすだけであれば、LambdaにTest機能がありますので、そちらを用いて動かしたいと思います。
ですが、もちろん今までお伝えしていたLINEの設定を行えば、LINEから起動させることももちろん可能です。

Amazon S3について

では、S3とはなんぞや?という方の為に、簡潔に説明していきましょう!

Amazon S3について

『Amazon Simple Storage Service』を、略してS3と言います。
要するにストレージサービスのことです。
もっと簡単に言うと、ファイルサーバーですね。
(ちなみにAPサーバは、EC2です。)

勿論無料枠も御座います。
5 GB の Amazon S3 ストレージ、20,000 GET リクエスト、2,000 PUT、COPY、POST、あるいは LIST リクエスト、データ送信 100 GB を毎月利用できます(S3 Standard ストレージクラス)。

S3に接続してみよう

ということで、早速S3に接続してみましょう。
S3にファイルを新規作成(書き込み) ⇒ 読み込み ⇒ 削除 を一気にやっていきたいと思います。
(ファイルの更新は「読み込み+書き込み」と同じため、省略します。)

1.S3を作成。

使用するサービス:S3
使用する機能:バスケット

「バケットを作成」ボタンを押下し、下記のキャプチャーのように設定します。

image.png

一番下の「バケットを作成」ボタンを押下すれば、S3の作成が完了です。

2.ロールを作成する

使用するサービス:IAM
使用する機能:ロール

ロールを設定します。

「ロールを作成」ボタンを押下し、「AWSのサービス」を選択。
ユースケースはLambdaからS3にアクセスするので、「Lambda」を選択します。
そして、「次へ」ボタンを押下します。

image.png

権限を設定します。

次に権限を設定していくのですが、こちらは前回記載しましたが、
まず検索ウィンドウで「S3」と検索し、その後「FullAccess」と「Execution」がつくものにチェックをつけましょう!!
「次へ」を押下します。
image.png

名前と設定の確認をします

名前はもちろん任意です。
内容を確認して、「ロールを作成」を押下します。
image.png

3.Lambdaで関数を作成する。

使用するサービス:Lambda
使用する機能:関数

関数を作成する

「関数の作成」ボタンを押下し、下記のキャプチャーのように設定します。

注意点として、「実行ロール」は上で設定したロールを選択してください。

image.png

コーディングの前に補足させて頂きます。
boto3からS3をインスタンス化する際、やり方が2種類あります。

  • boto3.client('s3')
  • boto3.resource('s3')

です。
違いとしては以下のようにあります。

  • Client APIはレスポンスが辞書型なので必要な情報を取り出しにくい
  • Client APIはHTTP API 操作との 1 対 1 のマッピングが提供される
  • Resource APIの方がオブジェクト指向っぽく書ける
  • Resource APIが用意されていないことがあるサービスもある

そして、色々調べてみたところ、
S3へのファイル書き込み系の処理では『Resource API』を、読み込み系の処理では『Client API』を使っているサンプルが多い様に見えましたので、今回の記事でもそのようにしたいと思います。

以下のようにソースを書き換えます。

-import json
-
-def lambda_handler(event, context):
-    # TODO implement
-    return {
-        'statusCode': 200,
-        'body': json.dumps('Hello from Lambda!')
-    }

+import json
+import boto3
+from datetime import datetime
+
+s3_resource = boto3.resource('s3')
+s3_client = boto3.client('s3')
+
+def lambda_handler(event, context):
+
+    ##########################################################
+
+    ###S3へデータを書き込みます。【Start】###
+    file_contents = '[{"name": "NAKAMURA","age": 80},{"name": "SATOU","age": 20},{"name": "KATOU","age": 30}]'
+    bucket = 'test-s3-2197-bucket'
+    key = 'test_s3.json'
+    bucketObj = s3_resource.Object(bucket,key)
+    response = bucketObj.put(Body=file_contents)
+    
+    print("response:")
+    print(response)
+    
+    ###S3へデータを書き込みます。【End】###
+    
+    ##########################################################
+    
+    ###S3のデータを読み込みます。【Start】###
+    #######################################
+    ###以下、本来は設定が必要だが、       ### 
+    ###書き込みの際に設定しているため、   ###
+    ###今回はコメントアウト。            ###
+    #bucket = 'test-s3-2197-bucket'     ###
+    #key = 'test_s3.json'               ###
+    #######################################
+    response = s3_client.get_object(Bucket=bucket, Key=key)
+    body = response['Body'].read()
+    
+    print("body:")
+    print(body)
+    ###S3のデータを読み込みます。【End】###
+    
+    ##########################################################
+    ###S3のファイルの削除。【Start】###
+    #s3_client.delete_object(Bucket=bucket, Key=key)
+    ###S3のファイルの削除。【End】###
+
+    return body

↓↓↓コピー用↓↓↓

import json
import boto3

s3_resource = boto3.resource('s3')
s3_client = boto3.client('s3')

def lambda_handler(event, context):

    ##########################################################

    ###S3へデータを書き込みます。【Start】###
    file_contents = '[{"name": "NAKAMURA","age": 80},{"name": "SATOU","age": 20},{"name": "KATOU","age": 30}]'
    bucket = 'test-s3-2197-bucket'
    key = 'test_s3.json'
    bucketObj = s3_resource.Object(bucket,key)
    response = bucketObj.put(Body=file_contents)
    
    print("response:")
    print(response)
    
    ###S3へデータを書き込みます。【End】###
    
    ##########################################################
    
    ###S3のデータを読み込みます。【Start】###
    #######################################
    ###以下、本来は設定が必要だが、       ### 
    ###書き込みの際に設定しているため、   ###
    ###今回はコメントアウト。            ###
    #bucket = 'test-s3-2197-bucket'     ###
    #key = 'test_s3.json'               ###
    #######################################
    response = s3_client.get_object(Bucket=bucket, Key=key)
    body = response['Body'].read()
    
    print("body:")
    print(body)
    ###S3のデータを読み込みます。【End】###
    
    ##########################################################
    ###S3のファイルの削除。【Start】###
    #s3_client.delete_object(Bucket=bucket, Key=key)
    ###S3のファイルの削除。【End】###

    return body

実行は最初に記載した通り、Lambdaの『Test』機能を使っていきましょう!!
image.png

上記の『Test』を押下すると、下記のような設定画面が出てくるので、任意のイベント名を設定し、イベント共有の設定を『プライベート』、そして最後に『保存』を押下します。
image.png

するとTestが開始されます。
上記で貼り付けたLambdaのソースが実行され、以下のようなログが出ます。
image.png

そして、最初は何もファイルがなかったですが、関数実行後はファイルが作成されております!!
image.png

ソースコード解説

簡単にですが、ソース解説も行いたいと思います。

インポート

import boto3

『import boto3』はAWSのサービスを使う際に、ほぼ必須となるImportになります。
しかも、LambdaがAWSのサービスであるため、AWS Lambdaで開発をしていれば、デフォルトでインストールされている為レイヤーを追加する必要はありませんが、AzureやGoogleクラウドの場合はレイヤーの追加が必要だと思われます。
その場合は下記のようなコマンドを使って、インストールしましょう。

sudo pip install boto3

当方はよく、Cloud9というAWSのサービスからインストールするようにしております。
(お手軽で便利ですよー!!)
今度それも記事にしたいと思います。

S3の呼び出し方法について

s3_resource = boto3.resource('s3')
s3_client = boto3.client('s3')

AWSサービスを呼び出す際、2つの呼び出し方があります。
それが、「resource」メソッドを呼び出すやり方と、「client」メソッドを呼び出すやり方です。
2023年にどうやら「resource」メソッドの方は非推奨となったようですが、一応2つの違いを記載します。

resource
●REST APIを呼び出すクライアント・インターフェース
●高レイヤーのオブジェクト指向なサービスアクセスが可能
client
●ORMっぽくAWSリソースを操作するリソース・インターフェース
 ⇒ORMとは『オブジェクト関係マッピング』のことです。
●低レイヤーのサービスのアクセスが可能

バケット名とキーについて

    bucket = 'test-s3-2197-bucket'
    key = 'test_s3.json'

途中、bucketとkeyを指定する箇所が御座いますが、bucketはS3で設定するので分かるかと思いますが、keyというのは、今回の例だとファイル名になりますが、本来的な意味では『フォルダ名+ファイル名』になります。
気をつけましょう!!

躓きやすい所に絞って解説しましたが、「名は体を現す」という言葉の通り、他はメソッド名を見れば解説は不要だと判断しました。
(それにハッカソンでサクッと読めて実装が出来るというのが、この備忘録の売りとしたいので、長々と書き続けるのはコンセプトと違うと思い・・・)
ということで、どうしてもわからない箇所がありましたら、コメント頂ければと思います。

総括

はい。
今回は一番簡単なLambdaとS3の連結部分について、記事を記載させて頂きました。
今回記載したことは、ほかのサービスでも基本となるところなので、覚えておくと他のサービスも簡単に連結させることが出来ると思います。

まとめ

  • 1.S3のバケットを作成する。
  • 2.IAMでロールを作成する。
  • 3.Lambdaで関数を作成する。
  • 4.Lambdaのソースを改修する。

※細かな設定がありますので、本編でちゃんと確認しながら進めることが、時間短縮のコツです。

次回は、AWSのAIサービスのAIサービスの一つ。
Rekoginitionに繋いでみたいと思います。

ということで、本日はここまでです。
少しでも参考になったと思いましたら、「いいね」や「ストック」を押していただけますと、今後の励みになりますので、是非とも宜しくお願い致します。

最後までお読み頂きありがとうございました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?