2
1

More than 1 year has passed since last update.

AWS ChaliceでS3に画像をアップロードしてみた

Posted at

はじめに

「自分のAWSアカウント作成してlambdaの勉強してみよう!」と思っていたところ、lambdaやAPI Gatewayなどの設定やら何やらでかなり苦労し挫折しかけていました。。。そんな時に「AWS Chalice」というかなり便利なフレームワークがあることを知り、希望が見えてきました!!!
もし、私と同じような状況の方がの記事を読んでいただけると嬉しいです!!!

AWS Chaliceとは

Amazon API Gateway と AWS Lambda による API 環境を実現してくれる、 AWS 製のサーバーレスアプリケーションのフレームワークのこと。
一応以下に、LambdaとAPI Gatewayについても記載します。

AWS Lambda

  • クラウド上にプログラムを定義し、インターネットを通じて実行できるサービス
  • サーバーやミドルウェアの管理はAWSが行ってくれるので、プログラムのことだけを考えれば良いというサービス

AWS API Gateway

  • あらゆる規模の REST、HTTP、および WebSocket API を作成、公開、維持、モニタリング、およびセキュア化するための AWS のサービス
  • HTTPベースで、標準のHTTTPメソッドを実装し、ステートレスなクライアント/サーバー通信を有効にするRestfulなAPIを作成するサービス

Chaliceのインストール

今回はローカル環境にpythonの仮想環境を作成し、Chaliceをインストールしました。

$ python3 --version
Python 3.9.7
$ python3 -m venv venv37
$ . venv37/bin/activate
$ python3 -m pip install chalice
$ chalice new-project chalice-sample
$ cd chalice-sample
# デプロイ時に設定が必要なため
$ aws configure

S3にテスト用のバケットを作成しておいてください。
これでChaliceの開発環境の構築は完了です。

S3に画像をアップロードする実装

実装についての説明はソース中にコメント記載してあるため割愛します。

app.py
import boto3
import os
import io
import cgi
from chalice import Chalice
from dotenv import load_dotenv
load_dotenv()

app = Chalice(app_name='chalice-sample')
app.debug = True
# s3関連設定
s3 = boto3.client('s3', region_name='ap-northeast-1')
BUCKET_NAME = os.getenv('BUCKET_NAME')

# test
@app.route('/')
def index():
    return {'hello': 'world'}

# API Gateway に multipart/form-data をバイナリとして扱うように指示する設定 
app.api.binary_types.append('multipart/form-data')

@app.route('/upload',methods=['POST'],content_types=['multipart/form-data'],cors=True)
def upload_file():
    # HTTPのボディをバイナリとして受け取る。
    body_to_binary = io.BytesIO(app.current_request.raw_body)

    # form解析
    environ = {'REQUEST_METHOD': 'POST'}
    headers = {'content-type': app.current_request.headers['content-type']}
    """
    - cgi.FieldStorageの引数の説明
     - fp : file pointerのことでボディ本体を表す。io.BytesIO()で読み込む必要あり。
     - environ : メソッドの操作
     - headers : リクエストで受け取ったヘッダー
    """
    form = cgi.FieldStorage(fp=body_to_binary, environ=environ, headers=headers)
    if len(form.list) > 0:
        try:
            for f in form.list:
                print("filename=",f.filename)
                s3.put_object(Bucket=BUCKET_NAME,Key=f.filename,Body=f.value)
                return {
                    'statusCode': 200,
                    'body': 'アップロード完了'
                }
        except:
            return {
                'statusCode': 500,
                'body': 'システム内部エラー発生'
            }

    else:
        return {
            'statusCode': 202,
            'body': 'アップロードするファイルを選択してください。'
        }

ファイルアップロードできるか試してみよう

まずは、Chaliceをローカルで動かす。

$ chalice local

Found credentials in shared credentials file: ~/.aws/credentials
Serving on http://127.0.0.1:8000

あとはGoogleの拡張機能であるTalend API Tasterを使ってテストしてみる。
image.png

アップロードが完了していることがわかる。S3の方はどうなっているかというと、、、
image.png

無事アップロードできていますね!よかった!

アプリをデプロイしてみよう

$ chalice deploy

image.png
無事、lambda関数とAPI Gatewayがデプロイされていることが分かります!

最後に

最後まで読んでいただき、ありがとうございます!今回はAWS ChaliceでS3に画像をアップロードしてみました。ChaliceがなかったらlambdaやAPI Gatewayの設定で挫折してここまで辿り着けなかったと思います。本当に助かった、、、、笑
まだまだAWSのことはわからないことだらけですが、せっかく自分のアカウントも作成したのでこれからどんどん勉強して色々な記事を投稿できたらなと思います。

2
1
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
2
1