13章 - S3 (前半)

やること

今回は,boto3を使い,S3を触っていく.まず,boto3というのは,PythonからAWS APIを操作するためのライブラリのことである.
boto3を使い,S3にファイルをアップロードやダウンロードを行う.



boto3の概要

まず,boto3でS3にファイルをアップロードする方法として,2種類ある.
以下に例を示す.

#client
client = boto3.client("s3")
client.upload_file(file_name,bucket_name,key)

#resource
s3 = boto3.resource("s3")
bucket = s3.Bucket(bucket_name)
bucket = upload_file(file_name,key)

clientを使う方法は,client以下の関数を逐次的に記述していく.そして,resourceを使う方法は,オブジェクトを生成し,そのオブジェクトに定義されているメソッドなどを使用して記述していく.
双方では,書き方は違えど実行されるAWS APIは共通なので,どちらでもかまわない.


S3の準備

S3を使うにあたって,今回はjupyterを使用する.まずは,デプロイからjupyterの起動までをやっていく.
デプロイを行うディレクトリは,前回も利用した場所で行う.
urhayataro.hatenablog.com

また,boto3はvenv内でインストールを行う.

cd learn-aws-by-coding-source-code/handson/bashoutter
python3 -m venv .env
source .env/bin/activate
pip install boto3
pip install -r requirements.txt
cdk deploy

デプロイしたときに表示されるBucketNameはひかえておく

次に,以下を入力し,表示されるURLにアクセスするとjupyterを利用することができる.

jupyter notebook

起動すれば,右上の「new」からプログラムを作成していく.



Basic IO

ここでは,先程立ち上げたjupyterを使い,テキストファイルのアップロードとダウンロードをやってみる.
まずは,boto3をインポートし,s3リソースを呼び出す.

import boto3
session = boto3.Session(profile_name="default")
s3 = session.resource("s3")

次に,バケットの名前を格納する変数を定義する.

bucket_name = "デプロイしたときのBucketName"
bucket = s3.Buclet(bucket_name)

最後に,テキストファイルを生成してバケットにアップロードしてみる.例では,tmp.txtにmyfile1とmyfile2というキーを付けてアップロードしている.その後,バケット内のオブジェクト一覧を取得してみる.

with open("tmp.txt", "w") as f:
      f.write("Hello world!")
bucket.upload_file("tmp.txt", "myfile1.txt")
bucket.upload_file("tmp.txt", "myfile2.txt")

objects = bucket.objects.all()
for o in objects:
      print(o.key)

実行すると,以下のような出力結果が返ってくる.


次に,生成したmyfile1.txtについて触ってみる.
まずは,ファイルのサイズと,最終更新日時の取得を行う.
objにmyfile1.txtを代入し,それを使って進めていく.

obj = bucket.Object("myfile1.txt")
print(obj.content_lengh)
print(obj.last_modified)

すると,以下のような出力になる.ファイルのサイズは,中身をHello world!としたので12が,あとは,それを編集(作成)した日時が出力されている.

次に,バケットににあるmyfile1.txtをdownloaded.txtという名前にしてローカルにダウンロードしてみる.

obj.download_file("downloaded.txt")

すると,ローカルにダウンロードされる.

ダウンロードができれば,myfile1.txtを削除しよう.更に,削除できたかを知るためにオブジェクト一覧を取得してみる.
myfile2.txtのみになっているはずだ.

obj.delete()

objects = bucket.objects.all()
for o in objects:
      print(o.key)

これでローカルとバケット間でのファイルをアップロード,ダウンロードができた.
長くなるので後半に続く.
urhayataro.hatenablog.com