Python
AWS
S3
boto3

AWS S3のオブジェクト(GLACIERも)を丸ごとダウンロードする


概要

S3バケットに保管されているオブジェクト(標準・GLACIER)を丸ごとダウンロードするスクリプトです。

S3に保管しているオブジェクトがライフサイクルルールでGLACIERストレージクラスにアーカイブされてしまったので書きました。


使い方

サンプルのバケット名と保存ディレクトリ名を書き換え、スクリプト名を指定してPythonインタプリタを起動します。

$ python restore_n_download.py

GLACIERからの復元には通常3時間~5時間かかるとのことなので、このスクリプトを一回実行して復元を開始し、3時間~5時間後にもう一回実行すればダウンロードできます。ダウンロード済みのファイルは処理を飛ばしますし、オブジェクトが復元中かどうかも知ることができます。


restore_n_download.py

# S3バケット内のオブジェクト群をダウンロードする

# GLACIERに移行したオブジェクトは復元を要求する
# https://qiita.com/seigo/items/d63d7d13ca330bd8f769

import boto3
import os

# 実際の値に書き換える
mybucket = 'awsexamplebucket' # S3バケット名
filter = '' # 絞込みたいキー名
basedir = '/Users/name/awsexamplebucket' # ダウンロードするディレクトリ
days = 1 # 復元されたコピーを使用可能な日数

def download(key):
savepath = '{0}/{1}'.format(basedir, key)
# ダウンロード済
if os.path.exists(savepath):
print('Already exists: %s' % key)
# 未ダウンロード
else:
savedir = os.path.dirname(savepath)
if not os.path.exists(savedir):
os.makedirs(savedir)
bucket.download_file(key, savepath)
print('Downloaded: %s' % key)

s3 = boto3.resource('s3')
bucket = s3.Bucket(mybucket)
for obj_sum in bucket.objects.all():
obj = s3.Object(obj_sum.bucket_name, obj_sum.key)
if filter in obj_sum.key:
# 対象のオブジェクト
if obj.storage_class == 'GLACIER':
# オブジェクトのストレージクラスがGLACIERである
# オブジェクトに復元要求がなければ要求
if obj.restore is None:
print('Submitting restoration request: %s' % obj.key)
obj.restore_object(RestoreRequest={'Days': days})
# 復元が進行中のオブジェクトを出力
elif 'ongoing-request="true"' in obj.restore:
print('Restoration in-progress: %s' % obj.key)
# 復元が完了しているオブジェクトをダウンロード
elif 'ongoing-request="false"' in obj.restore:
# print(download(obj_sum.key) + obj.key)
download(obj.key)
else:
# ストレージクラスがGLACIERでなければダウンロード
download(obj.key)



参照