【 Python 】ローカル → S3へファイルをアップロードする手順 ( boto3 )


はじめに

boto2を使って、ローカルストレージにあるファイルをアップロードするQiita記事はよく見かけるが、
boto3を使ったものがなかなか見つからなかったので、公式サイトを参考に実装したものを貼っておく。

開発環境

Python 3.6.1
pip 9.0.1

手順

  • パッケージインストール
  • Configファイル設定
  • 実装 (pythonソースコード)

パッケージインストール

boto3(AWS SDK for python)

$ pip install boto3

コマンドラインよりAWSのサービスを操作するためのパッケージも併せてインストールしておく。

$ pip install awscli

Configファイル生成

アクセスキー、シークレットキー、リージョン等をConfigファイルに書き込む。
下記コマンドを実行し、後は対話型にデータを入力していけばホームディレクトリ配下にファイルが生成される。

※ boto2では、ソース上よりAWSアクセスキー、シークレットキーを読み込んでいたが、
boto3では、Configファイルから上記2つキーを取得する。

$ aws configure
AWS Access Key ID [None]: xxxxxxxxxxxxxxxxxxxxxxx
AWS Secret Access Key [None]: xxxxxxxxxxxxxxxxxxx
Default region name [None]: xxxxxxxxxxxxxxxxxxxxx
Default output format [None]: xxxxxxxxxxxxxxxxxxx

生成されるファイル(2つ)

~/.aws/credentials
----------------------------------------------
[default]
aws_access_key_id = ACCESS_KEY_ID
aws_secret_access_key = SECRET_ACCESS_KEY
----------------------------------------------
~/.aws/config
----------------------------------------------
[default]
region = [xxxxxxxxxxxxxxxxx]
output = [xxxxxxxxxxxxxxxxx]
----------------------------------------------

ホームディレクトリに生成され、boto3実行時もホームディレクトリの上記ファイルを読みに行っているので、
.awsのディレクトリを移動させるとエラーが発生するので注意。

botocore.exceptions.NoCredentialsError: Unable to locate credentials

もし移動させると、上記のようなエラーが発生する。
まぁ、普通の人は移動させないんだろうけど。。。

実装 (Pythonソースコード)


# -*- coding: utf-8 -*-

import sys
import threading

import boto3

# boto3 (.aws/config)
BUCKET_NAME = 'YOUR_BUCKET_NAME'

class ProgressCheck(object):
    def __init__(self, filename):
        self._filename = filename
        self._size = int(os.path.getsize(filename))
        self._seen_so_far = 0
        self._lock = threading.Lock()
    def __call__(self, bytes_amount):
        with self._lock:
            self._seen_so_far += bytes_amount
            percentage = (self._seen_so_far / self._size) * 100
            sys.stdout.write(
                    "\r%s / %s (%.2f%%)" % (
                        self._seen_so_far, self._size,
                        percentage))
            sys.stdout.flush()


def UploadToS3():
    # S3Connection
    s3 = boto3.resource('s3')
    s3.Object(BUCKET_NAME, 'OBJECT_KEY (S3)').upload_file('UPLOAD_FILE_PATH (lOCAL)')

UploadToS3()  

OBJECT_KEY (S3) : S3でのオブジェクトキーを設定する。
UPLOAD_FILE_PATH (lOCAL) : アップロードするローカルファイルのパスを設定する。

終わりに

気が向いたら、boto2でのアップロード方法との比較も書きたいと思います。
最後までお読みいただき、ありがとうございました。

何か誤り、アップデート事項ございましたらご指摘お願いいたします。