AWS-Lambda + PythonでCSVデータをAWS-S3に書き込む

# AWS-Lambda + PythonでCSVデータをAWS-S3に書き込む

## はじめに

`Mac環境の記事ですが、Windows環境も同じ手順になります。環境依存の部分は読み替えてお試しください。`

### 目的

この記事を最後まで読むと、次のことができるようになります。

| No.  | 概要         | キーワード    |
| :--- | :----------- | :------------ |
| 1    | コーディング | Python, boto3 |
| 2    | Lambda設定   | Lambda        |

### 実行環境

| 環境           | Ver.    |
| :------------- | :------ |
| macOS Catalina | 10.15.3 |
| Python         | 3.7.3   |
| boto3          | 1.11.17 |

### ソースコード

実際に実装内容やソースコードを追いながら読むとより理解が深まるかと思います。是非ご活用ください。

[GitHub](https://github.com/nsuhara/python-lambda-write-s3.git)

### 関連する記事

- [Boto3](https://boto3.amazonaws.com/v1/documentation/api/latest/index.html)
- [AWS-Lambda + Python + CronでWEBスクレイピングを定期的に実行する](https://qiita.com/nsuhara/items/0d36600511fc162827f6)

## AWS-Lambdaの特徴

本サービスは従量課金制となります。ご留意ください。

- [特徴](https://aws.amazon.com/jp/lambda/features/)
- [料金](https://aws.amazon.com/jp/lambda/pricing/)

## 全体の流れ

1. Pythonコードを書く
2. Lambda関数を作成する
3. 環境変数を設定する

## 1. Pythonコードを書く

### コーディング

```app/lambda_function.py
"""app/lambda_function.py
"""

import os
import sys
from datetime import datetime, timedelta, timezone

from boto3.session import Session


def _localtime(time_zone):
    """_localtime
    """
    return datetime.now(timezone.utc)+timedelta(hours=int(time_zone))


def _write_to_s3(param):
    """_write_to_s3
    """
    access_key_id = param.get('aws_access_key_id')
    secret_access_key = param.get('aws_secret_access_key')
    region_name = param.get('aws_region_name')
    bucket_name = param.get('s3_bucket_name')
    file_name_format = param.get('s3_file_name_format')
    encode = param.get('s3_encode')
    data = param.get('data')

    session = Session(aws_access_key_id=access_key_id,
                      aws_secret_access_key=secret_access_key,
                      region_name=region_name)
    s3 = session.resource('s3')
    bucket = s3.Bucket(bucket_name)  # pylint: disable=no-member

    fname = '{}.csv'.format(_localtime(time_zone=9).strftime(file_name_format))
    print('fname: {}'.format(fname))
    obj = bucket.Object(fname)

    try:
        obj.put(
            Body=data.encode(encode, 'ignore'),
            ContentEncoding=encode,
            ContentType='text/csv'
        )
    except AttributeError as e:
        print(e)
        sys.exit()


def lambda_handler(event, context):
    """lambda_handler
    """
    print('event: {}'.format(event))
    print('context: {}'.format(context))

    param = {
        'aws_access_key_id': os.getenv('S3_ACCESS_KEY_ID', ''),
        'aws_secret_access_key': os.getenv('S3_SECRET_ACCESS_KEY', ''),
        'aws_region_name': os.getenv('S3_REGION_NAME', ''),
        's3_bucket_name': os.getenv('S3_BUCKET_NAME', ''),
        's3_file_name_format': os.getenv('S3_FILE_NAME_FORMAT', ''),
        's3_encode': os.getenv('S3_ENCODE', ''),
        'data': _localtime(time_zone=0).strftime('%Y-%m-%dT%H:%M:%S+00:00')
    }
    _write_to_s3(param=param)

    return {
        'status_code': 200
    }


if __name__ == '__main__':
    lambda_handler(event=None, context=None)
```

## 2. Lambda関数を作成する

[AWS-Lambda + Python + CronでWEBスクレイピングを定期的に実行する](https://qiita.com/nsuhara/items/0d36600511fc162827f6)の記事を参考に`zipのアップロード`まで実施する

## 3. 環境変数を設定する

### 環境変数

1. `環境変数`セクションの`編集`から設定する

| キー                 | 値                          |
| :------------------- | :-------------------------- |
| S3_ACCESS_KEY_ID     | {aws_access_key_id}         |
| S3_SECRET_ACCESS_KEY | {aws_secret_access_key}     |
| S3_REGION_NAME       | {region_name}               |
| S3_BUCKET_NAME       | {bucket}                    |
| S3_FILE_NAME_FORMAT  | e.g. release/%Y-%m/%Y-%m-%d |
| S3_ENCODE            | e.g. cp932                  |

`{}は環境毎に異なります。`