AWS Lambdaで任意のURLからファイルダウンロードしてS3に格納する

PythonAWSの勉強がてら、タイトル通りのスクリプトを書いてみた。

IAMの画面から AmazonS3FullAccess のポリシーをアタッチしたロールを作ってやって、Lamdaファンクションに指定してやれば動く。

使い方

下記3つを実行時のPayloadにJSONで指定して実行する。

  • bucket_name 格納先バケット名。存在しないバケットが指定された場合は、バケットをap-northeast-1に作成する。
  • url ダウンロード対象のURL
  • file_name 格納ファイル名

コード

import pycurl
import urllib
import boto3
from io import BytesIO

def lambda_handler(event, context):
    location = 'ap-northeast-1'
    s3client = boto3.client('s3')
    buckets = s3client.list_buckets()
    bucket_name = event["bucket_name"]
    if bucket_name not in buckets:
        bucket = s3client.create_bucket(Bucket=bucket_name,  CreateBucketConfiguration={
    'LocationConstraint': location})
    buffer = BytesIO()
    c = pycurl.Curl()
    c.setopt(pycurl.URL, str(event["url"]))
    c.setopt(pycurl.WRITEFUNCTION, buffer.write)
    c.perform()
    c.close()
    s3client.upload_fileobj(BytesIO(buffer.getvalue()), bucket_name, event["file_name"])

実行時のPayload例

{
  "url":"http://www.google.com/",
  "bucket_name":"mytestbucket",
  "file_name":"google.html"
}

留意点

  • ダウンロードしたデータをメモリに展開するので、大きなファイルのDLは出来ない。
  • もっとおしゃれな書き方は無いものか。